2013-08-26 2 views
14

Я смотрел на исходный код openjdk-1.7.0_25 и я видел этот метод:Java isNan, как это работает?

/** 
* 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?

ответ

17

Этот метод может возвращать истинную для некоторых операций, например:

System.out.println(Float.isNaN(0.0f/0.0f)); 
System.out.println(Double.isNaN(Math.sqrt(-1))); 

В основном, NaN представляет собой неопределенное значение. Значение 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 одного и того же типа с разными битовыми шаблонами.

+0

Таким образом, просто небольшой набор операций может возвращать 'NaN' и только с этими значениями он может возвращать' true' ... ok спасибо! – rascio

+0

@rascio. Да, этот метод вернет 'true' только для аргумента' NaN'. И может быть и другая операция, которая возвращает «NaN». Подобно 'Double.POSITIVE_INFINITY/Double.POSITIVE_INFINITY', аналогично для Negative infinity. –

+0

@rascio Кроме того, не забывайте, что если вы продолжаете вычислять с помощью этого значения «NaN», каждый результат всегда будет также «NaN». Теоретически да, только небольшой набор операций фактически генерирует «NaN», но если вы продолжаете вычислять с ним, каждая дальнейшая операция также вернет «NaN»! –

2

Потому что только NaN сравнивает ложь с самим собой. Поэтому он вернет true, когда вы передадите метод NaN.

Сравнение с NaN всегда возвращает неупорядоченный результат, даже если по сравнению с самим собой. ... Предикаты равенства и неравенства: без сигнализации, так что x = x возвращение false может быть использовано для проверки, является ли x тихим NaN.

Source

Это не только о Java, это верно и для всех языков следующих стандарта IEEE754.

Связанные вопрос: Why does Double.NaN==Double.NaN return false?

+1

это понимается по коду .. вы можете это продемонстрировать? – sanbhat

+0

@sanbhat: У меня есть обновленный код. Надеюсь, теперь это имеет смысл. – xyz

3

От Java Language Specification:

с плавающей точкой тестирования равенство выполняется в соответствии с правилами стандарта IEEE 754:

  • Если один из операндов является NaN, тогда результат == является ложным, но результат! = истинен. Действительно, тест x! = X истинен тогда и только тогда, когда значение x равно NaN. (Методы Float.isNaN и Double.isNaN также могут использоваться для проверки того, является ли значение NaN.)

  • Положительный ноль и отрицательный ноль считаются равными. Следовательно, -0.0 == 0.0 истинно, например.

  • В противном случае два независимых значения с плавающей точкой считаются неравными операторами равенства. В частности, существует одно значение, представляющее положительную бесконечность, а одно значение представляет отрицательную бесконечность; каждый сравнивает равный только с самим собой, и каждый сравнивает неравные со всеми другими значениями.

0

Насколько я знаю NaN value не равна anything.So, когда вы прошли float v, он никогда не равен ему самостоятельно.

1

Простой .. Nan всегда ! =NaN, эти значения ничем не равны. Смотрите this:!

Как уже было описано выше, NaN является неупорядоченным, поэтому цифровая операция сравнения с участием одного или два пренебрежимо малым возвращает ложь и любой = сравнение с участием NaN возвращает истину, включая й = х, когда x = NaN.

Так тестирование, если v != v достаточно, чтобы сказать, является ли value это NaN или нет.

Смежные вопросы