Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In what way do relational operators not obey the compareTo contract with floating point values?

Quoted from Effective Java - Second Edition by Joshua Bloch

For floating-point fields, use Double.compare or Float.compare in place of the relational operators, which do not obey the general contract for compareTo when applied to floating point values.

It doesn't elaborate on why this is the case.

So, my question is:

In what way do relational operators fail to obey the general contract for compareTo when used with floating point values?

like image 829
John Humphreys Avatar asked Oct 12 '12 20:10

John Humphreys


2 Answers

From the javadoc:

 public int compareTo(Double anotherDouble)

Compares two Double objects numerically. There are two ways in which comparisons performed by this method differ from those performed by the Java language numerical comparison operators (<, <=, ==, >=, >) when applied to primitive double values: Double.NaN is considered by this method to be equal to itself and greater than all other double values (including Double.POSITIVE_INFINITY). 0.0d is considered by this method to be greater than -0.0d. This ensures that the natural ordering of Double objects imposed by this method is consistent with equals.

like image 187
Kiersten Arnold Avatar answered Nov 15 '22 12:11

Kiersten Arnold


From JavaDoc for Double::compareTo

Compares two Double objects numerically. There are two ways in which comparisons performed by this method differ from those performed by the Java language numerical comparison operators (<, <=, ==, >= >) when applied to primitive double values:

  • Double.NaN is considered by this method to be equal to itself and greater than all other double values (including Double.POSITIVE_INFINITY).

  • 0.0d is considered by this method to be greater than -0.0d.

This ensures that Double.compareTo(Object) (which forwards its behavior to this method) obeys the general contract for Comparable.compareTo, and that the natural order on Doubles is consistent with equals.

    double d1 =Double.NaN;
    double d2 = Double.NaN;

    System.out.println(Double.valueOf(d1).equals(d2));    ---> true
    System.out.println(Double.valueOf(d1).compareTo(d2));  ---> 0
    System.out.println(d1 == d2);                          --->false
like image 42
Amit Deshpande Avatar answered Nov 15 '22 13:11

Amit Deshpande