23

I was looking at the openjdk-1.7.0_25 source code and I have seen this method:

/**
 * Returns {@code true} if the specified number is a
 * Not-a-Number (NaN) value, {@code false} otherwise.
 *
 * @param   v   the value to be tested.
 * @return  {@code true} if the argument is NaN;
 *          {@code false} otherwise.
 */
static public boolean isNaN(float v) {
    return (v != v);
}

I can't understand how it works, when this method can return true?

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
rascio
  • 8,968
  • 19
  • 68
  • 108

5 Answers5

26

That method can return true for certain operations, for example:

System.out.println(Float.isNaN(0.0f / 0.0f));
System.out.println(Double.isNaN(Math.sqrt(-1)));

Basically, NaN represents an undefined value. The value of 0.0 / 0.0 is NaN, and Nan != NaN. It may seem logical because Math.sqrt(-1) also gives you NaN.

See the javadoc of Double.NaN:

It is equivalent to the value returned by Double.longBitsToDouble(0x7ff8000000000000L)

And then Double.longBitsToDouble():

If the argument is any value in the range 0x7ff0000000000001L through 0x7fffffffffffffffL or in the range 0xfff0000000000001L through 0xffffffffffffffffL, the result is a NaN. No IEEE 754 floating-point operation provided by Java can distinguish between two NaN values of the same type with different bit patterns.

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • So just a little set of operation can return a `NaN` and just with that values it can return `true`...ok thanks! – rascio Aug 26 '13 at 11:04
  • @rascio. Yeah that method will return `true` for only a `NaN` argument. And there might be some other operation too, which returns `NaN`. Like `Double.POSITIVE_INFINITY / Double.POSITIVE_INFINITY`, similarly for Negative infinity. – Rohit Jain Aug 26 '13 at 11:07
  • @rascio Also, don't forget that if you keep calculating with that `NaN` value, every result is always also `NaN`. So theoretically yes, only a little set of operations actually generate `NaN`, but if you keep calculating with it, every further operation will also return `NaN`! – Timo Türschmann Aug 26 '13 at 11:09
  • NaN is just a placeholder for "This value was calculated using, directly or indirectly, the result of an impossible calculation.". It just does not make sense to say one meaningless answer is equal to another meaningless answer. – Patricia Shanahan Aug 26 '13 at 22:00
3

From Java Language Specification:

Floating-point equality testing is performed in accordance with the rules of the IEEE 754 standard:

  • If either operand is NaN, then the result of == is false but the result of != is true. Indeed, the test x!=x is true if and only if the value of x is NaN. (The methods Float.isNaN and Double.isNaN may also be used to test whether a value is NaN.)

  • Positive zero and negative zero are considered equal. Therefore, -0.0==0.0 is true, for example.

  • Otherwise, two distinct floating-point values are considered unequal by the equality operators. In particular, there is one value representing positive infinity and one value representing negative infinity; each compares equal only to itself, and each compares unequal to all other values.

Community
  • 1
  • 1
axtavt
  • 239,438
  • 41
  • 511
  • 482
2

Because only NaN compares false with itself. So it will return true when you pass NaN to the method.

A comparison with a NaN always returns an unordered result even when comparing with itself. ... The equality and inequality predicates are non-signaling so x = x returning false can be used to test if x is a quiet NaN.

Source

It not just about Java, It is also true for all languages following IEEE754 standard.

Related question : Why does Double.NaN==Double.NaN return false?

Community
  • 1
  • 1
Ajinkya
  • 22,324
  • 33
  • 110
  • 161
1

Simple.. Nan is always != NaN, these values are not equal to anything. See this:

As has already been described, NaN is unordered, so a numeric comparison operation involving one or two NaNs returns false and any != comparison involving NaN returns true, including x!=x when x is NaN.

So testing if v != v is sufficient to tell whether the value is NaN or not.

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
Maroun
  • 94,125
  • 30
  • 188
  • 241
0

As far as I know NaN value is not equal to anything.So when you passed float v,It's never not equal to it self.

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307