3 ms·
IMO, this only makes sense if you assume that NaNs can propagate useful information. In the real world, seeing a NaN basically just means that your math is wron
by adgjlsfhk1 5y ago
IMO, this only makes sense if you assume that NaNs can propagate useful information. In the real world, seeing a NaN basically just means that your math is wrong. From my perspective, the only 2 possibly useful semantics for NaN are to either just always throw an error (and not have NaN), or to say that it's equal to itself. Any other option means that == isn't an equivalence relation which pretty much completely breaks math.
- adrian_b 5y agoOn all CPUs it is possible to enable the undefined operation exception. In that case, no NaN will ever appear, but all undefined operations will throw an exception. So one of the behaviors that you want is available in any computing device and it should always be selected by all programmers who want to avoid testing whether an operand is a NaN. The only problem appears when you write some function in a library for which there is a policy that it should not require a certain FPU configuration to work, but it should behave correctly regardless of the FPU configuration selected by the user. However the second behavior desired by you is not good, because that is the one that completely breaks math. On the set of all floating-point numbers, "==" is a partial equivalence relation. It is not a total equivalence relation. Attempting to forcibly define it as a total relation leads only to inconsistent results. On any set where there is only a partial equivalence relation and a partial order relation instead of total relations, the result of the comparison of 2 set elements can have 4 values: "==", "<", ">" and "unordered", instead of only 3 values, like for total relations. To the 3 comparison values of total relations, there are 2^3 - 2 = 6 corresponding relational operators. To the 4 comparison values of partial relations, there are 2^4 - 2 = 14 corresponding relational operators (e.g. "not less than" is not the same as ">=" but it is "equal, greater or unordered", so to the 6 operators of total orders, their 6 negations are added, plus other 2 operators, "unordered" and "not unordered"). Working correctly with partial relations is not really more complex than working with total relations. They are unfamiliar only because for some reason they are neglected in school, where only total relations are discussed in detail.
- adgjlsfhk1 5y agoYou keep saying that == on floating point is a partial relation, but that's only true because of the way NaN currently compares. Floating point exists as a model of the real numbers, on which equality is total, so a system modeling them should absolutely keep that if possible, which it is. It's fine to have a non-reflexive operation that behaves like == does for floats, but making that the primary equivalence relation is absolutely bonkers, since 2 NaN values with the same bit-pattern are completely indistinguishable from each other, yet compare non-equal. Furthermore, I can't think of any reason that Inf==Inf should be true, while NaN==Nan is false. In both cases, they can be modeling different numbers (although that is true of literally any floating point number). If there were a major advantage to making == non-reflexive, that would be one thing, but I've been programming for most of my life, (including a lot of floating point), and I've yet to come across a place where I was glad that NaN!=NaN.