ПРИХОДИТЕ УЧИТЬСЯ НОВОЙ ПРОФЕССИИ ЛЕТОМ СО СКИДКОЙ ДО 70%Забронировать скидку
logo

Как проверить, является ли double NaN в Java: лучший метод

Пройдите тест, узнайте какой профессии подходите и получите бесплатную карьерную консультацию
В конце подарим скидку до 55% на обучение
Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Определить, равно ли значение типа double значению NaN, можно с использованием метода Double.isNaN(value). При попытке сравнить NaN напрямую через value == Double.NaN результат не будет получен, так как по стандарту IEEE 754 NaN не может равняться ни одному числу, включая самого себя. Для проверки значения можно использовать следующий код:

Java
Скопировать код
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:

Java
Скопировать код
double nanValue = Double.NaN;
System.out.println(nanValue == Double.NaN); // Возвращает false, что может быть неожиданным  💔

Это происходит из-за стандарта IEEE 754 для чисел с плавающей точкой, согласно которому NaN не равен любому значению, включая самого себя.

NaN не равен NaN? Верно!

В результате получаем удивительную ситуацию, когда NaN не равен(!=) NaN. Несмотря на то что это звучит странно, но это полностью согласуется со стандартом IEEE 754:

Java
Скопировать код
double nanValue = Double.NaN;
System.out.println(nanValue != nanValue); // Все-таки правда!

Метод isNaN() для объектов Double

Если вы работаете с объектами типа Double, то используйте вместо этого метод isNaN():

Java
Скопировать код
Double obj = new Double(Double.NaN);
boolean isNan = obj.isNaN(); // Возвращает true для NaN объектов

Подходит для работы с объектами Double, а не примитивами double.

Проверка на null и NaN для объектов Double

Если работаете с объектами Double, которые могут быть null или NaN, используйте следующую комбинированную проверку:

Java
Скопировать код
Double value = /* экземпляр Double может быть null или NaN */;
boolean isNullOrNan = (value == null || value.isNaN());

Визуализация

Посмотрим, как воспринимает Java значение NaN:

Java
Скопировать код
double value = /* double выражение */;
if(Double.isNaN(value)) {
    System.out.println("🕵️‍♂️ Да, действительно NaN.");
} else {
    System.out.println("🔍 Нет, это вполне обычное число.");
}

Результаты проверки на NaN:

Markdown
Скопировать код
Значение Double         | Результат проверки
----------------------- | -----------------
3.1415                  | 🔍 Число
Double.NaN              | 🕵️‍♂️ Правильно, NaN!
Double.POSITIVE_INFINITY | 🔍 Число
0.0                     | 🔍 Число

Таким образом, для определения NaN очень полезен метод Double.isNaN().

NaN на практике: Применение и особенности

Исключаем влияние NaN на вычисления

NaN может появиться в процессе вычислений и затем распространяться:

Java
Скопировать код
double result = 0.0 / 0.0; // Результат – NaN
System.out.println(Double.isNaN(result)); // Правда, найдено значение NaN!

Проверка NaN в модульных тестах с JUnit

JUnit содержит метод assertEquals() , который работает и с NaN:

Java
Скопировать код
assertEquals(Double.NaN, result, 0.0); // Тест будет успешным, если result – NaN

Выгодное решение для перестраховки и обеспечения стабильной прямоты пути вашего кода!

Сравнения с учетом NaN

Когда необходимо провести сравнение со значением NaN, стоит использовать такие инструменты как Comparator в Java:

Java
Скопировать код
Comparator<Double> nanSafeComparator = Comparator.comparingDouble(Double::doubleValue);

Такой компаратор позволяет провести сравнение, учитывая особенности NaN.

Полезные материалы