6 ms·
> Also, NaR compares equal to itself, fixing one of the biggest bugs in floating point. I thought that was by-design? Just like how NULL != NULL in SQL?
by DaiPlusPlus 5y ago
> Also, NaR compares equal to itself, fixing one of the biggest bugs in floating point.
I thought that was by-design? Just like how NULL != NULL in SQL?
- adgjlsfhk1 5y agoAs far as I can tell (see https://stackoverflow.com/questions/1565164/what-is-the-rationale-for-all-comparisons-returning-false-for-ieee754-nan-values https://stackoverflow.com/questions/1565164/what-is-the-rati...), the only reason for it was that early chips had no other single instruction that could be used to implement isnan, so they decided to use == for that purpose.
- adrian_b 5y agoNo, a NaN not being equal to itself is the correct behavior for an order relation that is a partial order, not a total order. The bug is neither in the FP standard nor in the implementations. The bug is in almost all programming languages, which annoyingly provide only the 6 relational operators needed for total order relations. To deal with partial order relations, which appear not only in operations with floating-point numbers, but also in many other applications, you need 14 relational operators. Only when they are provided by the programming language you no longer need to test whether a number is a NaN, because you can always use the appropriate relational operator, depending on what the test must really do. The 2 relational operators "is equal to" and "is either equal to or unordered", are distinct operators, exactly like "is equal to" and "is equal to or greater" are distinct. If you do not have distinct symbols for"is equal to" and "is either equal to or unordered", the compiler cannot know whether the test must be true or false when a NaN operand is encountered. If you do not know which of the 2 operators must be used, you must think more about it, because your program will be wrong in exceptional cases. Specifying a stupid rule like a NaN being equal to itself and claiming that the correct behavior is a bug shows a dangerous lack of understanding of mathematics, which is not acceptable for someone designing a new number representation method (even if a single NaN value is used, it can be generated as a result of different, completely unrelated computations, and there is no meaningful way in which those results can be considered equal). In general almost all programming languages are designed by people without experience in numerical computation, who completely neglect to include in the language the features required for the operations with floating-point numbers, resulting in an usually dreadful support for the IEEE floating-point arithmetic standard, even after almost 40 years since it became widespread. It is not the standard which must be corrected, but the programming languages, which do not provide good access to what the hardware can do. Also the education of the programmers is lacking because most of them are familiar only with the 6 relational operators for total orders, instead of being equally familiar with the 14 operators for partial orders. Partial orders are encountered extremely frequently. If only the 6 relational operators are available in such cases, then they must always be preceded by a test for unordered operands. Forgetting the additional test guarantees errors. To avoid the double tests that are needed in most programming languages, it may be possible to define macros corresponding to all the 14 relational operators, but they cannot be as convenient as proper support in the language.
- adgjlsfhk1 5y agoIMO, 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 ago