Подтвердить что ты не робот

Каким образом реляционные операторы не подчиняются контракту compareTo с плавающими значениями?

Цитата из Effective Java - второе издание Джошуа Блоха

Для полей с плавающей точкой используйте Double.compare или Float.compare вместо реляционных операторов, которые не подчиняются общему контракту для compareTo при применении к значениям с плавающей запятой.

Он не уточняет, почему это так.

Итак, мой вопрос:

Каким образом реляционные операторы не могут выполнить общий контракт для compareTo при использовании с значениями с плавающей запятой?

4b9b3361

Ответ 1

Из javadoc:

 public int compareTo(Double anotherDouble)

Сравнивает два двойных объекта с численностью. Существует два способа сравнения сравнений, выполненных этим методом, от операций, выполняемых операторами численного сравнения языка Java (<, < =, ==, > =, > ) при применении к примитивным двойным значениям: Double.NaN считается этим методом равным себе и больше всех других двойных значений (включая Double.POSITIVE_INFINITY). 0.0d считается, что этот метод будет больше -0,0d. Это гарантирует, что естественный порядок объектов Double, налагаемых этим методом, согласуется с равными.

Ответ 2

Из java doc Двойной # compareTo

Сравнивает два двойных объекта с численностью. Существует два способа сравнения сравнений, выполненных этим методом, от тех, которые выполняются операторами численного сравнения языка Java (<, < =, ==, >= > ) при применении к примитивным двойным значениям:

  • Double.NaN считается этим методом равным себе и больше всех других двойных значений (включая Double.POSITIVE_INFINITY).

  • 0.0d считается этим методом больше -0.0d.

Это гарантирует, что 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