NaN does not match itself, and the reason can be understood from the answer posted by Stephen here :
My understanding from talking with Kahan is that NaN! = NaN for two pragmatic reasons:
that x == y should be equivalent to x - y == 0 when possible (not being a theorem of real arithmetic, this makes the hardware implementation of the comparison more efficient from a space point of view, which was of utmost importance at the time of development of the standard - note however, that this is violated at x = y = infinity, so its not a big reason on its own; it could be bent to x - y == 0 or NaN ).
more importantly, there was no isnan( ) predicate at the time that NaN was formalized in arithmetic 8087; It was necessary to provide programmers with a convenient and effective means of detecting NaN values that are independent of programming languages that provide something like isnan( ) , which can take many years. Quote Report to the moderator by writing on the topic:
If there were no ways to get rid of NaNs, they would be useless, as vague on CRAY; as soon as someone collides, the calculation is better to stop than to continue for an indefinite time to an indefinite conclusion. This is why some NaN operations should deliver results without NaN. What operations? ... The exception is the C predicates "x == x" and "x! = X", which are respectively 1 and 0 for any infinite or finite number x, but vice versa if x is not a number (NaN); they provide the only simple exclusion difference between NaN and numbers in languages that lack the word for NaN and the predicate IsNaN (x).
Note that this is also logic that rules out returning something like “Not-A-Boolean”. Perhaps this pragmatism was inappropriate, and the standard should have required isnan( ) , but this could make NaN almost impossible to use efficiently and conveniently for several years while the world was waiting for the adoption of a programming language. I am not convinced that this would be a reasonable compromise.
source share