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, он никогда не был равен ему.