IEEE 754 defines a system of floating-point arithmetic. Its equality operator tests whether two numbers are equal. (This is different from testing whether two objects are identical.) NaN represents something that is Not A Number. Two NaNs can be identical, but they cannot be numbers that are equal because they are not numbers.
One reason this is important is that NaN is used to convey the information that an operation has gone astray. For example, suppose two numbers x
and y
had been calculated with floating-point operations. However, further suppose that, due to rounding errors, at some point when calculating x
, a value that ideally would have been a small positive value was instead a small negative value, and then its square root was taken. The result is a NaN. Similarly, while calculating y
, a value that ideally would have been less than one was slightly greater than one when its arcsine was taken, and the result is again a NaN.
Now x
and y
are both NaN. If x == y
returned true, it would be indicating that the two computed values are equal. But, in fact, we have no idea whether the values intended to be computed are equal. So this is not the result we want.
Similarly, if we assigned results for x < y
or x > y
when one or both of x
or y
was a NaN, then floating-point algorithms would get wrong results. If one operand is a NaN, then the answer we want to “Which order are x
and y
in?” Is “We do not know.” So x == y
, x < y
, and x > y
all return false when either operand is a NaN, and floating-point algorithms must be designed with this in mind.
One reason that NaNs were created was so that floating-point operations do not have to stop when an error occurs. A very lengthy floating-point algorithm working with many numbers can continue executing, and then the program can examine the results at the end to see if there are any NaNs. Then it is up to the program to handle those in whatever way is suitable for that particular program. (In general, there is not a single solution for what to do about problems in floating-point algorithms. So IEEE 754 was designed to give implementations some flexibility. Programs can fix up results or divert their operations as needed.)
Platforms that provide IEEE-754 operations generally ought to provide both a comparison for numeric equality (for testing arithmetic properties) and a comparison for sort order and identity (for use when inserting objects into sorted lists or other structures such as dictionaries).