From this question I learned Double.NaN is not equal to itself.
I was verifying this for myself and noticed this is not the case if you wrap Double.NaN in a Double instance. For example:
public class DoubleNaNTest {
public static void main(String[] args) {
double primitive = Double.NaN;
Double object = new Double(primitive);
// test 1 - is the primitive is equal to itself?
boolean test1 = primitive == primitive;
// test 2 - is the object equal to itself?
boolean test2 = object.equals(object);
// test 3 - is the double value of the object equal to itself?
boolean test3 = object.doubleValue() == object.doubleValue();
System.out.println("Test 1 = " + test1);
System.out.println("Test 2 = " + test2);
System.out.println("Test 3 = " + test3);
}
}
Outputs:
Test 1 = false
Test 2 = true
Test 3 = false
It seems to me that all three tests should evaluate to false as all three operations are equivalent (as they are if you use something other then Double.NaN).
Could someone explain what's going on here?
What is going on is that the equals
method deliberately deviates from IEE floating point. Quoting from the Javadoc for the equals(Object)
method of java.lang.Double.
However, there are two exceptions:
- If d1 and d2 both represent Double.NaN, then the equals method returns true, even though Double.NaN==Double.NaN has the value false.
- If d1 represents +0.0 while d2 represents -0.0, or vice versa, the
equal test has the value false, even
though +0.0==-0.0 has the value true.This definition allows hash tables to operate properly.
The upshot is that if you want 100% IEE floating point compatibility you need to explicitly unbox the java.lang.Double
instances and compare the resulting double
values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With