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

Java подписали ноль и бокс

В последнее время я написал проект на Java и заметил очень странную функцию с двойной/двойной реализацией. Двойной тип в Java имеет два 0, то есть 0.0 и -0.0 (подписанные ноль). Странно, что:

0.0 == -0.0

принимает значение true, но:

new Double(0.0).equals(new Double(-0.0))

имеет значение false. Кто-нибудь знает причину этого?

4b9b3361

Ответ 1

Все объяснено в javadoc:

Обратите внимание, что в большинстве случаев для двух экземпляров класса Double, d1 и d2 значение d1.equals(d2) истинно тогда и только тогда, когда

   d1.doubleValue() == d2.doubleValue() 

также имеет значение true. Однако есть два исключения:

  • Если d1 и d2 оба представляют Double.NaN, то метод equals возвращает true, хотя Double.NaN == Double.NaN имеет значение false.
  • Если d1 представляет +0.0, тогда как d2 представляет -0.0, или наоборот, равный тест имеет значение false, хотя значение +0.0 == - 0.0 имеет значение true.

Это определение позволяет хэш-таблицам работать правильно.


Теперь вы можете спросить, почему 0.0 == -0.0 - true. На самом деле они не являются строго идентичными. Например:

Double.doubleToRawLongBits(0.0) == Double.doubleToRawLongBits(-0.0); //false

является ложным. Однако JLS требует ( "в соответствии с правилами стандарта IEEE 754" ), что:

Положительный нуль и отрицательный нуль считаются равными.

следовательно, 0.0 == -0.0 истинно.

Ответ 2

Важно, чтобы использовать знак с нулевым знаком в классе Double. (Нагрузки опытных Java-программистов нет).

Короткий ответ заключается в том, что (по определению) "-0,0 меньше 0,0" во всех методах, предоставляемых классом Double (то есть equals(), compare(), compareTo() и т.д.)

Двойной позволяет всем числам с плавающей запятой "полностью упорядочиваться на числовой строке". Примитивы ведут себя так, как пользователь будет думать о вещах (определение реального мира)... 0d = -0d

Следующие фрагменты иллюстрируют поведение...

final double d1 = 0d, d2 = -0d;

System.out.println(d1 == d2); //prints ... true
System.out.println(d1 < d2);  //prints ... false
System.out.println(d2 < d1);  //prints ... false
System.out.println(Double.compare(d1, d2)); //prints ... 1
System.out.println(Double.compare(d2, d1)); //prints ... -1

Есть и другие сообщения, которые актуальны и хорошо объясняют фон...

1: Почему числа с плавающей запятой имеют подписанные нули?

2: Почему Java Double.compare(двойной, двойной) реализован так, как он есть?

И слово осторожности...

Если вы этого не знаете, в Double Class "- 0.0 меньше 0.0" , вы можете получить доступ к ним при использовании таких методов, как equals() и compare() и compareTo() из Double в логических тестах. Например, посмотрите...

final double d3 = -0d; // try this code with d3 = 0d; for comparison

if (d3 < 0d) {     
    System.out.println("Pay 1 million pounds penalty");
} else {           
    System.out.println("Good things happen"); // this line prints
}


if (Double.compare(d3, 0d) < 0) { //use Double.compare(d3, -0d) to match the above behaviour
    System.out.println("Pay 1 million pounds penalty"); // this line prints
} else {                              
    System.out.println("Good things happen"); 
}

и для равных вы можете попробовать... new Double (d3).equals(0d) || новый двойной (d3).equals(-0d)

Ответ 3

Используя оператор ==, вы сравниваете значения. С равными вы сравниваете объекты.