Почему удваивается.NaN = = Двойной.NaN return false?
Я просто изучал вопросы OCPJP и я нашел этот странный код:
public static void main(String a[]) {
System.out.println(Double.NaN==Double.NaN);
System.out.println(Double.NaN!=Double.NaN);
}
когда я запустил код, я получил:
false
true
как вывод false
когда мы сравниваем две вещи, которые похожи друг на друга? Что значит NaN
В смысле?
9 ответов:
NaN означает "не число".
спецификация языка Java (JLS) третье издание говорит:
операция переполнения порождает знаковую бесконечность, операция переполнения порождает денормализованное значение или знаковый ноль, а операция, не имеющая математически определенного результата, порождает NaN. Все числовые операции с NaN в качестве операнда производят NaN в результате. Как уже было описано, NaN неупорядочен, поэтому числовой операция сравнения с участием одного или двух nans возвращает
false
и ни!=
сравнение с участием NaN возвращаетtrue
, включаяx!=x
, когдаx
Нэн.
NaN по определению не равно любому числу, включая NaN. Это является частью стандарта IEEE 754 и реализуется CPU / FPU. Это не то, что JVM должен добавить какую-либо логику для поддержки.
http://en.wikipedia.org/wiki/NaN
сравнение с NaN всегда возвращает неупорядоченный результат даже при сравнении с самим собой. ... Предикаты равенства и неравенства не сигнализируют, поэтому x = x, возвращающий false, можно использовать для проверки, если х-тихая Нэн.
Java рассматривает все NaN как тихий NaN.
зачем такая логика
NaN
означаетNot a Number
. Что такое не число? Что угодно. Вы можете иметь что угодно в одной стороне и что угодно в другой стороне, поэтому ничто не гарантирует, что оба равны.NaN
исчисляется сDouble.longBitsToDouble(0x7ff8000000000000L)
и как вы можете видеть в документацииlongBitsToDouble
:если аргумент имеет любое значение в диапазоне
0x7ff0000000000001L
через0x7fffffffffffffffL
или0xfff0000000000001L
через0xffffffffffffffffL
, результат aNaN
.и
NaN
логически обрабатывается внутри API.
документация
/** * A constant holding a Not-a-Number (NaN) value of type * {@code double}. It is equivalent to the value returned by * {@code Double.longBitsToDouble(0x7ff8000000000000L)}. */ public static final double NaN = 0.0d / 0.0;
кстати,
NaN
и протестировано в качестве примера кода:/** * Returns {@code true} if the specified number is a * Not-a-Number (NaN) value, {@code false} otherwise. * * @param v the value to be tested. * @return {@code true} if the value of the argument is NaN; * {@code false} otherwise. */ static public boolean isNaN(double v) { return (v != v); }
решение
что вы можете сделать, это использовать
compare
/compareTo
:
Double.NaN
считается этим методом равным самому себе и больше, чем все остальныеdouble
значения (в том числеDouble.POSITIVE_INFINITY
).Double.compare(Double.NaN, Double.NaN); Double.NaN.compareTo(Double.NaN);
или
equals
:если
this
иargument
иDouble.NaN
, тогда элементequals
возвращаетtrue
, хотяDouble.NaN==Double.NaN
имеет значениеfalse
.Double.NaN.equals(Double.NaN);
это может быть не прямой ответ на вопрос. Но если вы хотите проверить, если что-то равно
Double.NaN
вы должны использовать это:double d = Double.NaN Double.isNaN(d);
вернет
true
The javadoc для двойной.Нэн говорит:
константа, содержащая значение Not-a-Number (NaN) типа
double
. Это эквивалентно значению, возвращаемомуDouble.longBitsToDouble(0x7ff8000000000000L)
.интересно, что источник
Double
определяетNaN
таким образом:public static final double NaN = 0.0d / 0.0;
специальное поведение, которое вы описываете, жестко связано с JVM.
NaN-это специальное значение, которое обозначает "не число"; это результат некоторых недопустимых арифметических операций, таких как
sqrt(-1)
, и имеет (иногда раздражает) имущества,NaN != NaN
.
в, стандарт IEEE для арифметики с плавающей запятой для чисел двойной точности,
представление стандарта с плавающей запятой двойной точности IEEE требуется 64-битное слово, которое может быть представлено как пронумерованное от 0 до 63, слева направо
где,
S: Sign – 1 bit E: Exponent – 11 bits F: Fraction – 52 bits
если
E=2047
(всегоE
are1
) иF
Не равно нулю, тоV=NaN
("не номер")что означает
если все
E
бит равен 1, и если есть какой-либо ненулевой бит вF
числоNaN
.поэтому, среди прочих, все следующие цифры
NaN
,0 11111111 0000000000000000010000000000000000000000000000000000 = NaN 1 11111111 0000010000000000010001000000000000001000000000000000 = NaN 1 11111111 0000010000011000010001000000000000001000000000000000 = NaN
в частности, вы не можете протестировать
if (x == Double.NaN)
чтобы проверить, равен ли конкретный результат
Double.NaN
, потому что все значения" не число " считаются различными. Тем не менее, вы можете использоватьDouble.isNaN
метод:if (Double.isNaN(x)) // check whether x is "not a number"
Не число представляет результат операций, результат которых не может быть представлен числом. Самая известная операция-0/0, результат которой неизвестен.
по этой причине, NaN не равен ничему (включая другие не-число значений). Для получения дополнительной информации, просто проверьте страницу Википедии:http://en.wikipedia.org/wiki/NaN
по этому ссылке, оно имеет различные ситуации и трудно запомнить. Вот как я их помню и различаю.
NaN
означает "математически неопределенный", например:" результат 0, разделенный на 0, не определен "и потому, что он не определен, поэтому"сравнение, связанное с неопределенным, конечно, не определено". Кроме того, он работает больше как математические предпосылки. С другой стороны, как положительное, так и отрицательное бесконечное предопределено и окончательно, например " положительное или отрицательный бесконечный большой хорошо определен математически".