Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding Double autoboxing

Consider the following example:

public static void main(String[] args) {
    double x1 = 0.0, y1 = -0.0;
    Double a1 = x1, b1 = y1;
    System.out.println(x1 == y1);       //1, true
    System.out.println(a1.equals(b1));  //2, false

    double x2 = 0.0, y2 = 0.0;
    Double a2 = x2, b2 = y2;
    System.out.println(x2 == y2);       //3, true
    System.out.println(a2.equals(b2));  //4, true

    double x3 = 0.0/0.0, y3 = 0.0/0.0;
    Double a3 = x3, b3 = y3;
    System.out.println(x3 != y3);       //5, true
    System.out.println(!a3.equals(b3)); //6, false
}

I tried to understand the autoboxing for Double, but could not. Why does the //2 print false, but //4 prints true whereas both //1 and //3 prints true. Why are they autoboxed in a different way?

Consulting the following JLS 5.1.7 section I realized that it's not specicified:

If p is a value of type double, then:

  • If p is not NaN, boxing conversion converts p into a reference r of class and type Double, such that r.doubleValue() evaluates to p

  • Otherwise, boxing conversion converts p into a reference r of class and type Double such that r.isNaN() evaluates to true

So, are //2, //4 and //6 yeild in unspecified behavior and might end up in different results depending on the implementation?

like image 975
St.Antario Avatar asked Mar 17 '16 05:03

St.Antario


2 Answers

All JAVA numeric types are signed unless specified differently

So, 0.0 is represented in binary as 0000000........0000000

-0.0 is represented as 10000000........0000000

Now, from what I understand, when you use equals() , the comparison is done in a bit-by-bit fashion from the 2 memory locations, so it fails in your case.

FROM THE java.lang.Double package

Double.equals(Double) is implemented as follows

public boolean equals(Object obj) {
    return (obj instanceof Double)
           && (doubleToLongBits(((Double)obj).value) ==
                  doubleToLongBits(value));
}
like image 120
Ayush Gupta Avatar answered Oct 08 '22 01:10

Ayush Gupta


The Double equals method is documented in the API documentation. The double == operation is documented in the Java Language Specification.

For most pairs of numbers they have the same result, but they are based on different conventions.

The double == is compatible with IEEE 754 arithmetic, in which a NaN is not equal to anything, not even itself, but 0.0 and -0.0 are equal.

Double is designed to have an equals method is compatible with its compareTo, reflecting a total order, and with its hashCode, so hash tables will work with Double keys. NaN is treated as equal to itself, and -0.0 is less than, rather than equal to, 0.0.

like image 37
Patricia Shanahan Avatar answered Oct 07 '22 23:10

Patricia Shanahan