Java isNan, как это работает?
Я смотрел исходный код openjdk-1.7.0_25
, и я видел этот метод:
/**
* 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 argument is NaN;
* {@code false} otherwise.
*/
static public boolean isNaN(float v) {
return (v != v);
}
Я не могу понять, как это работает, когда этот метод может вернуть true
?
Ответы
Ответ 1
Этот метод может возвращать true для определенных операций, например:
System.out.println(Float.isNaN(0.0f / 0.0f));
System.out.println(Double.isNaN(Math.sqrt(-1)));
В принципе, NaN
представляет значение undefined. Значение 0.0 / 0.0
равно NaN
и Nan != NaN
. Это может показаться логичным, потому что Math.sqrt(-1)
также дает вам NaN
.
См. javadoc Double.NaN
:
Это эквивалентно значению, возвращаемому Double.longBitsToDouble(0x7ff8000000000000L)
И затем Double.longBitsToDouble()
:
Если аргументом является любое значение в диапазоне от 0x7ff0000000000001L
до 0x7fffffffffffffffL
или в диапазоне от 0xfff0000000000001L
до 0xffffffffffffffffL
, результат равен NaN
. Никакая операция с плавающей запятой IEEE 754, предоставляемая Java, не может различать два значения NaN одного и того же типа с разными битовыми шаблонами.
Ответ 2
Из Спецификация языка Java:
Тестирование равенства с плавающей точкой выполняется в соответствии с правилами стандарта IEEE 754:
-
Если либо операнд NaN, то результат == является ложным, но результат равен = true. Действительно, тест x!= X истинен тогда и только тогда, когда значение x равно NaN. (Методы Float.isNaN и Double.isNaN также могут использоваться для проверки того, является ли значение NaN.)
-
Положительный нуль и отрицательный нуль считаются равными. Следовательно, -0.0 == 0.0 истинно, например.
-
В противном случае два разных значения с плавающей запятой считаются неравными операторами равенства. В частности, существует одно значение, представляющее положительную бесконечность, а одно значение представляет отрицательную бесконечность; каждый сравнивает равный только с самим собой, и каждый сравнивает неравные со всеми другими значениями.
Ответ 3
Потому что только NaN сравнивает false с самим собой. Поэтому он вернет true, когда вы передадите метод NaN
.
Сравнение с NaN всегда возвращает неупорядоченный результат, даже если по сравнению с самим собой.... Предикаты равенства и неравенства без сигнализации, так что x = x, возвращающее false, может быть использовано для проверки, является ли x спокойный NaN.
Источник
Это не только о Java, но и для всех языков, следующих по стандарту IEEE754.
Связанный вопрос: Почему Double.NaN == Double.NaN возвращает false?
Ответ 4
Простой.. Nan
всегда != Nan
, эти значения ничем не равны. См. this:
Как уже было описано, NaN неупорядочен, поэтому числовое операция сравнения с участием одного или двух NaN возвращает false и любой != сравнение с NaN возвращает true, , включая x!= x, когда x равно NaN.
Итак, тестирование, если v != v
достаточно, чтобы определить, является ли value
Nan
или нет.
Ответ 5
Насколько я знаю значение NaN не равно никому. Так что, когда вы проходили float v
, он никогда не был равен ему.