问题
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
?
回答1:
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
through0x7fffffffffffffffL
or in the range0xfff0000000000001L
through0xffffffffffffffffL
, the result is aNaN
. No IEEE 754 floating-point operation provided by Java can distinguish between two NaN values of the same type with different bit patterns.
回答2:
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.
回答3:
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?
回答4:
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.
回答5:
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.
来源:https://stackoverflow.com/questions/18442503/java-isnan-how-it-works