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

3

11

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?

Tie answered 12/10, 2012 at 20:51 Comment(2)
Related: https://mcmap.net/q/37335/-why-use-float-floattointbits-in-java-float-comparisonsCammi
These clases allow for NaN, (Not A Number) values.Nobe
T
6

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.

Tender answered 12/10, 2012 at 20:54 Comment(0)
S
4

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
Suilmann answered 12/10, 2012 at 20:54 Comment(1)
But, notably, it is not consistent with the relational operators.Suttle
T
1

According to [Joshua_Bloch] Effective_Java, 3rd Edition

Prior editions of this book(2nd Edition) recommended that compareTo methods compare integral primitive fields using the relational operators < and >, and floating point primitive fields using the static methods Double.compare and Float.compare. In Java 7, static compare methods were added to all of Java’s boxed primitive classes. Use of the relational operators < and > in compareTo methods are verbose and error-prone and no longer recommended.

When comparing field values in the implementations of the compareTo methods, avoid the use of the < and > operators. Instead, use the static compare methods in the boxed primitive classes or the comparator construction methods in the Comparator interface.

Tambratamburlaine answered 8/1, 2019 at 9:38 Comment(1)
How does this answer the question ?Ingrained

© 2022 - 2024 — McMap. All rights reserved.