Float.NaN == Float.NaN - PullRequest
       32

Float.NaN == Float.NaN

28 голосов
/ 18 февраля 2012

Почему это сравнение дает мне «ложь»?Я посмотрел на источник, и Float.NaN определяется как

/** 
 * A constant holding a Not-a-Number (NaN) value of type
 * <code>float</code>.  It is equivalent to the value returned by
 * <code>Float.intBitsToFloat(0x7fc00000)</code>.
 */
public static final float NaN = 0.0f / 0.0f;

РЕДАКТИРОВАТЬ: удивительно, если я сделаю это:

System.out.println("FC " + (Float.compare(Float.NaN, Float.NaN)));

это даст мне 0.Так что Float.compare() считает, что NaN равно самому себе!

Ответы [ 3 ]

61 голосов
/ 18 февраля 2012

Используйте Float.isNaN для проверки значений NaN.

35 голосов
/ 18 февраля 2012

Поскольку Java реализует стандарт IEEE-754 с плавающей запятой, который гарантирует, что любое сравнение с NaN вернет false (кроме !=, который возвращает true)

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

def isNan(val):
     return val != val
0 голосов
/ 21 сентября 2015

Все, что мне нужно сказать, это: Википедия о NaN .

Написано довольно четко. Интересная часть состоит в том, что NaN с плавающей запятой общего стандарта выражает NaN таким образом:

s111 1111 1xxx xxxx xxxx xxxx xxxx xxxx

s - знак (отрицательный или положительный), 1 - показатель степени, а x - полезная нагрузка.

Глядя на полезную нагрузку, NaN не равен ни одному NaN, и есть редкие шансы, что эта информация полезной нагрузки будет интересна вам как разработчику (например, комплексные числа).

Другое дело, что в стандарте есть сигнализация и вполне NaN. Сигнальный NaN (sNaN) означает NaN, который должен вызвать реакцию как исключение. Это следует использовать, чтобы сказать вслух, что у вас есть проблема в вашем уравнении. Тихий NaN (qNaN) - это NaN, который молча передается.

sNaN, создавший сигнал, преобразуется в qNaN, чтобы в дальнейшем не генерировать больше сигналов в последующих операциях. Помните, что некоторые системы определяют i ^ 0 = 1 как константу, для которой NaN ^ 0 = 1 имеет место. Так что есть случаи, когда люди рассчитывают с NaN.

Итак, в конце я бы сказал: qNaN! = SNaN, но это внутреннее и недоступно для пользователя (вы не можете это проверить). Смешайте платеж и знак (да, у вас может быть отрицательный и положительный NaN), и мне кажется, что всегда возвращать NaN! = NaN выглядит гораздо более мудрым выбором, который я наконец научился ценить -> Я никогда не буду жаловаться или удивляться о неравенстве NaN снова. Слава людям, которые так задумчиво дали нам такой хороший стандарт!

Кстати: Java использует положительный NaN с полезной нагрузкой 0 (все x - нули).

...