4 ms·
Every calculation will have to check for NaN, so it's a non-starter when you need a lot of float calculations.
by lifthrasiir 10y ago
Every calculation will have to check for NaN, so it's a non-starter when you need a lot of float calculations.
- yorwba 10y agoThe problem was in the context of looking up min_by_key with the key being a floating-point number, so I think the only NaN-check necessary should be for that key. I did not intend to imply that it should be done for all calculations, only those that need totally-ordered floats. (Or if you are really sure NaN will never happen, you leave out the check altogether, and claim total ordering anyway.)
- lifthrasiir 10y agoI guess that is a particularly bad use case of specialization, which itself is proposed as an RFC [1] and approved for implementation. It would look pretty similar to, say, C++'s `vector<T>` and `vector<bool>` split, because it does something more than what it should do. Probably the better solution is to merge PartialOrd and Ord, as the benefit from having two traits has been always unclear (I personally have no strong opinion against or for that though). [1] https://github.com/rust-lang/rfcs/blob/master/text/1210-impl-specialization.md https://github.com/rust-lang/rfcs/blob/master/text/1210-impl...
- frubar 10y agoIf the type proved there could be no NaN, why would the check be needed?
- lifthrasiir 10y ago0.0 is a finite number that yields NaN when divided by itself. The initial checking is not sufficient.
- infogulch 10y agoSo check on construction, when doing operations with other unchecked floats, and when dividing. Any other operations that could produce a NaN? Wait, are +-Inf considered unordered? Edit: Nope. inf == inf, so you should only have to worry about NaN. https://is.gd/Xi5jdr https://is.gd/Xi5jdr
- lifthrasiir 10y agoIf you want the full list: 0/0, ±inf/±inf, 0 x ±inf, ±inf x 0, inf + (-inf), (-inf) + inf, inf - inf, (-inf) - (-inf). This list is large enough to make NaN checking inefficient.
- infogulch 10y agoThanks. Yeah maybe not. It seems like the right way is to add min/max fns to the Iterator trait for PartialOrd that ignore items where partial_ord returns None.
- yorwba 10y agoNot all partial orders have well-defined min/max, though. Ideally, you would want traits for meet/join semi-lattices, but I'm not sure how much abstract algebra you can inflict on the average Rustacean. Then there is the whole problem of NaN is incomparable with everything, so you'd have to use a non-standard definition of semi-lattice to allow for that. And do you want max(NaN, 0) to be NaN or 0? There is a case to be made for either possibility.
- infogulch 10y agoIf I'm writing a game I don't really care if one of many operations accidentally resulted in NaN I would like to treat NaN like SQL treats NULL: pretend it doesn't exist. I can't glean useful information out of it, might as well try to get something from the rest of the data. Then again according to float semantics, sum of a list containing NaN must be NaN, so it would make sense to extend that principle to min/max. But the naive implementation of min/max will never output NaN because NaN always compares false. (... unless NaN is the first element. ugly.) Maybe making it explicit would be best: Make an explicit fn for float collections that filters out NaN in an Iterator, then claim that Item is totally ordered. I'm too much of a rust noob to know if this is possible. (playground here I come!)