Каким образом реляционные операторы не подчиняются контракту compareTo с плавающими значениями?
Цитата из Effective Java - второе издание Джошуа Блоха
Для полей с плавающей точкой используйте Double.compare или Float.compare вместо реляционных операторов, которые не подчиняются общему контракту для compareTo при применении к значениям с плавающей запятой.
Он не уточняет, почему это так.
Итак, мой вопрос:
Каким образом реляционные операторы не могут выполнить общий контракт для compareTo при использовании с значениями с плавающей запятой?
Ответы
Ответ 1
Из javadoc:
public int compareTo(Double anotherDouble)
Сравнивает два двойных объекта с численностью. Существует два способа сравнения сравнений, выполненных этим методом, от операций, выполняемых операторами численного сравнения языка Java (<, < =, ==, > =, > ) при применении к примитивным двойным значениям: Double.NaN считается этим методом равным себе и больше всех других двойных значений (включая Double.POSITIVE_INFINITY). 0.0d считается, что этот метод будет больше -0,0d. Это гарантирует, что естественный порядок объектов Double, налагаемых этим методом, согласуется с равными.
Ответ 2
Из java doc Двойной # compareTo
Сравнивает два двойных объекта с численностью. Существует два способа сравнения сравнений, выполненных этим методом, от тех, которые выполняются операторами численного сравнения языка Java (<, < =, ==, >= > ) при применении к примитивным двойным значениям:
Это гарантирует, что Double.compareTo(Object) (который переводит его поведение на этот метод) подчиняется общему контракту для Comparable.compareTo и что естественный порядок на парном согласуется с равными.
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