Reputation: 7226
Why does this comparison give me 'false'? I looked at the source and Float.NaN is defined as
/**
* A constant holding a Not-a-Number (NaN) value of type
* <code>float</code>. It is equivalent to the value returned by
* <code>Float.intBitsToFloat(0x7fc00000)</code>.
*/
public static final float NaN = 0.0f / 0.0f;
EDIT: surprisingly, if I do this:
System.out.println("FC " + (Float.compare(Float.NaN, Float.NaN)));
it gives me 0
. So Float.compare()
does think that NaN is equal to itself!
Upvotes: 30
Views: 31192
Reputation: 30206
Because Java implements the IEEE-754 floating point standard which guarantees that any comparison against NaN
will return false (except !=
which returns true)
That means, you can't check in your usual ways whether a floating point number is NaN, so you could either reinterpret both numbers as ints and compare them or use the much cleverer solution:
def isNan(val):
return val != val
Upvotes: 38
Reputation: 5513
All I need to say is: Wikipedia About NaN.
It is written quite clearly. The interesting part is that the floating point NaN of the common standard expresses a NaN this way:
s111 1111 1xxx xxxx xxxx xxxx xxxx xxxx
The s is the sign (negative or positive), the 1's are the exponent and the x is regarded as a payload.
Looking at the payload a NaN is not equal any NaN and there are rare chances that these information of the payload are interesting for you as a developer (e.g. complex numbers).
Another thing is that in the standard they have signalling and quite NaN. A signalling NaN (sNaN) means an NaN that should raises a reaction like a exception. It should be used to say out loud that you have a problem in your equation. A quiet NaN (qNaN) is a NaN that is silently passed on.
A sNaN that created a signal is converted to a qNaN to not further produce any more signals in subsequent operations. Remember some system define i^0 = 1 as a constant that NaN^0 = 1 holds true. So there are cases where people calculate with NaN.
So in the end I would go with this: qNaN != sNaN but this is internal and is not observable for the user (you cant check that). Mix along the payment and the sign (yes you can have negative and positive NaN) and it appears to me that always return NaN != NaN looks like a much wiser choice that I finally learned to appreciate -> I will never ever complain or wonder about the inequality of NaN again. Praise the folks who were that thoughtful giving us such a good standard!
By the way: Java uses a positive NaN with a payload of 0 (all x are zeros).
Upvotes: 0