Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Double.NaN equal itself when wrapped in a Double instance?

Tags:

java

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?

like image 200
Chris Harcourt Avatar asked Sep 11 '09 01:09

Chris Harcourt


1 Answers

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.

like image 92
Stephen C Avatar answered Oct 04 '22 01:10

Stephen C