Java подписали ноль и бокс
В последнее время я написал проект на Java и заметил очень странную функцию с двойной/двойной реализацией. Двойной тип в Java имеет два 0, то есть 0.0 и -0.0 (подписанные ноль). Странно, что:
0.0 == -0.0
принимает значение true
, но:
new Double(0.0).equals(new Double(-0.0))
имеет значение false
. Кто-нибудь знает причину этого?
Ответы
Ответ 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
Используя оператор ==, вы сравниваете значения. С равными вы сравниваете объекты.