Как проверить, является ли double NaN в Java: лучший метод
Быстрый ответ
Определить, равно ли значение типа double значению NaN, можно с использованием метода Double.isNaN(value). При попытке сравнить NaN напрямую через value == Double.NaN результат не будет получен, так как по стандарту IEEE 754 NaN не может равняться ни одному числу, включая самого себя. Для проверки значения можно использовать следующий код:
double value = Double.NaN;
boolean isNan = Double.isNaN(value); // вернуть true, если значение равно NaN
System.out.println("Значение " + (isNan ? "равно NaN." : "не равно NaN."));
Метод Double.isNaN() встроен в класс Double Java и является надёжным механизмом для проверки значения на NaN.

Подробности: Что такое NaN
В языке программирования Java, NaN обозначает "не число" (Not-a-Number) и является специальным значением типа double, которое возникает в результате математических операций, не имеющих численного результата.
Ошибка при сравнении на равенство
При сравнении значения типа double с Double.NaN напрямую всегда возвращается false. Это связано с особенностями NaN:
double nanValue = Double.NaN;
System.out.println(nanValue == Double.NaN); // Возвращает false, что может быть неожиданным 💔
Это происходит из-за стандарта IEEE 754 для чисел с плавающей точкой, согласно которому NaN не равен любому значению, включая самого себя.
NaN не равен NaN? Верно!
В результате получаем удивительную ситуацию, когда NaN не равен(!=) NaN. Несмотря на то что это звучит странно, но это полностью согласуется со стандартом IEEE 754:
double nanValue = Double.NaN;
System.out.println(nanValue != nanValue); // Все-таки правда!
Метод isNaN() для объектов Double
Если вы работаете с объектами типа Double, то используйте вместо этого метод isNaN():
Double obj = new Double(Double.NaN);
boolean isNan = obj.isNaN(); // Возвращает true для NaN объектов
Подходит для работы с объектами Double, а не примитивами double.
Проверка на null и NaN для объектов Double
Если работаете с объектами Double, которые могут быть null или NaN, используйте следующую комбинированную проверку:
Double value = /* экземпляр Double может быть null или NaN */;
boolean isNullOrNan = (value == null || value.isNaN());
Визуализация
Посмотрим, как воспринимает Java значение NaN:
double value = /* double выражение */;
if(Double.isNaN(value)) {
System.out.println("🕵️♂️ Да, действительно NaN.");
} else {
System.out.println("🔍 Нет, это вполне обычное число.");
}
Результаты проверки на NaN:
Значение Double | Результат проверки
----------------------- | -----------------
3.1415 | 🔍 Число
Double.NaN | 🕵️♂️ Правильно, NaN!
Double.POSITIVE_INFINITY | 🔍 Число
0.0 | 🔍 Число
Таким образом, для определения NaN очень полезен метод Double.isNaN().
NaN на практике: Применение и особенности
Исключаем влияние NaN на вычисления
NaN может появиться в процессе вычислений и затем распространяться:
double result = 0.0 / 0.0; // Результат – NaN
System.out.println(Double.isNaN(result)); // Правда, найдено значение NaN!
Проверка NaN в модульных тестах с JUnit
JUnit содержит метод assertEquals() , который работает и с NaN:
assertEquals(Double.NaN, result, 0.0); // Тест будет успешным, если result – NaN
Выгодное решение для перестраховки и обеспечения стабильной прямоты пути вашего кода!
Сравнения с учетом NaN
Когда необходимо провести сравнение со значением NaN, стоит использовать такие инструменты как Comparator в Java:
Comparator<Double> nanSafeComparator = Comparator.comparingDouble(Double::doubleValue);
Такой компаратор позволяет провести сравнение, учитывая особенности NaN.


