Я только изучал вопросы 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
значит?
In [1]: NaN==NaN Out[1]: False
Double.NaN==Double.NaN
должно действительно возвращать true, еслиDouble.NaN
были типаjava.lang.Double
. Тем не менее, его тип является примитивнымdouble
, иdouble
применяются операторские правила (которые требуют этого неравенства для соответствия IEEE 754, как объяснено в ответах).Ответы:
NaN означает «не число».
Спецификация языка Java (JLS) третьего издания гласит :
источник
false
. Так что этот стандарт отличается от Java тем, что IEEE требует этого(NAN != NAN) == false
.NaN по определению не равен ни одному числу, включая NaN. Это является частью стандарта IEEE 754 и реализуется процессором / FPU. Это не то, что JVM должна добавить какую-либо логику для поддержки.
http://en.wikipedia.org/wiki/NaN
Ява рассматривает весь NaN как тихий NaN.
источник
Почему эта логика
NaN
значитNot a Number
. Что не число? Что-нибудь. У вас может быть что угодно с одной стороны и что угодно с другой стороны, поэтому ничто не гарантирует, что оба равны.NaN
рассчитывается сDouble.longBitsToDouble(0x7ff8000000000000L)
и, как вы можете видеть в документацииlongBitsToDouble
:Кроме того,
NaN
логически рассматривается внутри API.Документация
Кстати,
NaN
это тестирование в качестве образца кода:Решение
Что вы можете сделать, это использовать
compare
/compareTo
:Или
equals
:источник
NaN != NaN
ложь может сделать программы более сложными, чемNaN != NaN
быть правдой? Я знаю, что IEEE принял решение много лет назад, но с практической точки зрения я никогда не видел случаев, когда это было бы полезно. Если предполагается, что операция выполняется до тех пор, пока последовательные итерации не дадут одинакового результата, две последовательные итерации приведут к тому, что NaN будет «естественно» определен как условие выхода, если бы не это поведение.f(f(f...f(x)))
, и он находитy=f[n](x)
для некоторогоn
такое, что результатf(y)
неотличим отy
, тоy
он будет неотличим от результата любого более глубоко вложенногоf(f(f(...f(y)))
. Даже если кто-то хочетNaN==NaN
быть ложным, то бытьNan!=Nan
также ложным будет менее «удивительно», чемx!=x
быть истинным для некоторых х.Double.NaN
неDouble
, ноdouble
, поэтому вопрос связан с поведениемdouble
. Хотя существуют функции, которые могут проверять отношение эквивалентности, включающееdouble
значения, единственный известный мне ответ на вопрос «почему» (который является частью первоначального вопроса) - «потому что некоторые люди в IEEE не думали, что тестирование на равенство должно определить отношение эквивалентности ". Кстати, есть ли какой-то краткий идиоматический способ проверкиx
иy
эквивалентности с использованием только примитивных операторов? Все известные мне формулировки довольно неуклюжи.Это может быть не прямой ответ на вопрос. Но если вы хотите проверить, что-то равно
Double.NaN
вам, следует использовать это:Это вернется
true
источник
Javadoc для Double.NaN говорит все это:
Интересно, что источник для
Double
определяетNaN
таким образом:Особое поведение, которое вы описываете, встроено в JVM.
источник
согласно стандарту IEEE для арифметики с плавающей запятой для чисел двойной точности,
где,
Что значит,
Если все
E
биты равны 1, и если есть какой-либо ненулевой бит,F
то число равноNaN
.Поэтому, в частности, все последующие номера
NaN
,В частности, вы не можете проверить
проверить, равен ли конкретный результат
Double.NaN
, потому что все значения «не числа» считаются различными. Однако вы можете использоватьDouble.isNaN
метод:источник
NaN - это специальное значение, которое обозначает «не число»; это результат некоторых недопустимых арифметических операций, таких как
sqrt(-1)
, и имеет (иногда раздражающее) свойство thatNaN != NaN
.источник
Не число представляет результат операций, результат которых не может быть представлен числом. Самая известная операция - 0/0, результат которой неизвестен.
По этой причине NaN не равен ничему (включая другие не-числовые значения). Для получения дополнительной информации, просто посетите страницу википедии: http://en.wikipedia.org/wiki/NaN
источник
0/0
.0/0
всегда NaN, но NaN может быть результатом других операций - таких как2+NaN
:an operation that has no mathematically definite result produces NaN
согласно ответу @AdrianMitevПо этой ссылке , он имеет различные ситуации и трудно запомнить. Вот как я их помню и различаю.
NaN
означает «математически не определено», например: «результат 0, деленный на 0, не определен», и поскольку он не определен, то «сравнение, связанное с неопределенным, конечно, не определено». Кроме того, это больше похоже на математические предпосылки. С другой стороны, как положительная, так и отрицательная бесконечность предопределены и окончательны, например, «положительное или отрицательное бесконечно большое хорошо определено математически».источник