4 ms·
> Rust floating-point types simply don't have Eq implementations (they have PartialEq only), passing them somewhere where you need an equality-comparable type i
by thedufer 6y ago
> Rust floating-point types simply don't have Eq implementations (they have PartialEq only), passing them somewhere where you need an equality-comparable type is a compilation error.
While this is true, you can still say `NaN == NaN` and get false. I claim that that's still the behavior I was describing.
> OCaml is the only other example I'm aware of (it treats nan as a normal value with a well-behaved place in the order).
Again, kind of true - for physical and structural equality it does a bitwise-comparison. However, most people recommend against those equality operators because they are misleading in many cases, and the float-specific equality operator does what I described.
In what ways are bitwise-comparison wrong? For structured data (say, binary-tree backed maps) this is clearly bad because there are potentially multiple representations that we would consider equivalent. But even for floats it is bad - `0 == -0` should be true, but will not be. Further, two different NaNs will be compare as false even though two of the same NaN will compare as true (you're not supposed to be able to distinguish between different representations of NaN).
- lmm 6y ago> While this is true, you can still say `NaN == NaN` and get false. I claim that that's still the behavior I was describing. Point taken; I do think it would be better for the method on PartialEq to not be called "==". But Rust does offer a standard distinction between well-behaved equality and not, and floats are not considered to implement well-behaved equality, which comes close to what I'm asking for. Like, if JavaScript had `NaN === NaN` then I'd consider that morally a counterexample to what you're talking about, because === is (in a sense) the standard equality operator in JavaScript; in the same way, I'd consider Eq::== to be the standard equality operator in Rust. > Again, kind of true - for physical and structural equality it does a bitwise-comparison. However, most people recommend against those equality operators because they are misleading in many cases, and the float-specific equality operator does what I described. I think that's the right way to do it. Generic code using the generic == expects it to have the standard properties - in particular x == x for any x. Code that uses a float-specific operator can be prepared for float-specific behaviour. > In what ways are bitwise-comparison wrong? For structured data (say, binary-tree backed maps) this is clearly bad because there are potentially multiple representations that we would consider equivalent. But even for floats it is bad - `0 == -0` should be true, but will not be. Further, two different NaNs will be compare as false even though two of the same NaN will compare as true (you're not supposed to be able to distinguish between different representations of NaN). This is true as far as it goes. Equally, having 0 == -0 is bad (it breaks substitutability, since 1 / 0.0 != 1 / -0.0), and having x != x is super bad. Really there is just no good general-purpose comparison for IEEE 754 floats, and so they should either not implement generic == at all (in languages where that's possible), be avoided by default and hidden away in an "unsafe" area of the standard library, or both.