Signed zero double equivalent (as in ==), but Double.compare (double, double)! = 0

I came across something strange in comparing double zeros. Depending on how the double zero primitives are initiated, the Double.compare (double, double) method may or may not assume that they are "equal" (may or may not return 0).

Comparing the different values ​​double double: s using == always reports them as equal. If they are equal in terms of ==, they should (should) be equal in terms of the comparison method. They are not!

Check out this program:

public class CompareZeros {

public static void main(final String[] args) {

    final double negDbl = -0.0;
    final double posInt = 0;
    final double posDbl = 0.0;
    final double negInt = -0;

    CompareZeros.compare("negDbl <-> posInt", negDbl, posInt);
    CompareZeros.compare("negDbl <-> posDbl", negDbl, posDbl);
    CompareZeros.compare("negDbl <-> negInt", negDbl, negInt);

    CompareZeros.compare("posInt <-> negDbl", posInt, negDbl);
    CompareZeros.compare("posInt <-> posDbl", posInt, posDbl);
    CompareZeros.compare("posInt <-> negInt", posInt, negInt);

    CompareZeros.compare("posDbl <-> negDbl", posDbl, negDbl);
    CompareZeros.compare("posDbl <-> posInt", posDbl, posInt);
    CompareZeros.compare("posDbl <-> negInt", posDbl, negInt);

    CompareZeros.compare("negInt <-> negDbl", negInt, negDbl);
    CompareZeros.compare("negInt <-> posInt", negInt, posInt);
    CompareZeros.compare("negInt <-> posDbl", negInt, posDbl);

}

static void compare(final String id, final double arg0, final double arg1) {

    System.out.print(id + ": ");

    if (arg0 == arg1) {
        if (Double.compare(arg0, arg1) == 0) {
            System.out.println("OK");
        } else {
            System.out.println("Strange, and must be wrong!");
        }
    } else {
        if (Double.compare(arg0, arg1) == 0) {
            System.out.println("Strange, but perhaps logically ok");
        } else {
            System.out.println("Consistent...");
        }
    }

}
}

He outputs this:

negDbl <-> posInt: Strange, and must be wrong!
negDbl <-> posDbl: Strange, and must be wrong!
negDbl <-> negInt: Strange, and must be wrong!
posInt <-> negDbl: Strange, and must be wrong!
posInt <-> posDbl: OK
posInt <-> negInt: OK
posDbl <-> negDbl: Strange, and must be wrong!
posDbl <-> posInt: OK
posDbl <-> negInt: OK
negInt <-> negDbl: Strange, and must be wrong!
negInt <-> posInt: OK
negInt <-> posDbl: OK
+6
source share
2 answers

Double.compare is documented equivalent

public static int compare (double d1, double d2)

. , :

   new Double(d1).compareTo(new Double(d2))

compareTo, Comparable, , :

, . , .

, IEEE 754 :

, IEEE 754, :

  • NaN, .

  • , NaN, , , .

  • .

... , , .


, , .

+1

Double.compare JDK, . :

public static int compare(double d1, double d2) {
    if (d1 < d2)
        return -1;           // Neither val is NaN, thisVal is smaller
    if (d1 > d2)
        return 1;            // Neither val is NaN, thisVal is larger

    // Cannot use doubleToRawLongBits because of possibility of NaNs.
    long thisBits    = Double.doubleToLongBits(d1);
    long anotherBits = Double.doubleToLongBits(d2);

    return (thisBits == anotherBits ?  0 : // Values are equal
            (thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
             1));                          // (0.0, -0.0) or (NaN, !NaN)
}

, . . . -0.0 0.0 - . 0.0 , -0.0. - 0, - -9223372036854775808.

docs :

0.0d -0.0d.

-0 ?

, -0 - , 0, 0. 0 double.

, == , JLS - 15.21.1:

15.21.1. == !=

...

IEEE 754:

...

  • .
+6

All Articles