Значение NaN
Значение NaN (сокращение от Not-A-Number) обозначает «не число». Такое значение возникает при попытках сделать недопустимую математическую операцию.
Пример
Давайте умножим строку с буквами на число:
console.log(‘aaa’ * 3);
Результат выполнения кода:
Пример
Давайте попробуем разделить одну строку на другую:
console.log(‘aaa’ / ‘bbb’);
После выполнения кода мы также получим NaN :
Пример
Теперь давайте суммируем значение NaN с числом:
console.log(NaN + 3);
Результат выполнения кода:
Смотрите также
- функцию isNaN ,
которая осуществляет проверку на NaN
NaN в Java
Проще говоря, NaN — это числовое значение типа данных, которое означает «не число».
В этом кратком руководстве мы объясним значение NaN в Java и различные операции, которые могут создавать или использовать это значение.
2. Что такое NaN ?
NaN обычно указывает на результат недопустимых операций. Например, попытка разделить ноль на ноль является одной из таких операций.
Мы также используем NaN для непредставимых значений. Квадратный корень из -1 является одним из таких случаев, поскольку мы можем описать значение ( i ) только комплексными числами.
Стандарт IEEE для арифметики с плавающей запятой (IEEE 754) определяет значение NaN . В Java этот стандарт реализуют типы с плавающей запятой float и double .
Java определяет константы NaN для типов float и double как Float .NaN и Double.NaN :
“ Константа, содержащая значение Not-a-Number (NaN) типа double. Это эквивалентно значению, возвращаемому Double.longBitsToDouble(0x7ff8000000000000L)».
«Константа, содержащая значение Not-a-Number (NaN) типа float. Это эквивалентно значению, возвращаемому Float.intBitsToFloat(0x7fc00000)».
У нас нет такого типа констант для других числовых типов данных в Java.
3. Сравнение с NaN
При написании методов на Java мы должны проверять, что ввод действителен и находится в ожидаемом диапазоне. Значение NaN не является допустимым входом в большинстве случаев. Поэтому мы должны убедиться, что входное значение не является значением NaN , и соответствующим образом обработать эти входные значения.
NaN нельзя сравнивать ни с каким значением плавающего типа. Это означает, что мы получим false для всех операций сравнения, включающих NaN (кроме «!=», для которого мы получаем true ).
Мы получаем истину для « x != x» тогда и только тогда , когда x равно NaN:
System.out.println("NaN == 1 = " + (NAN == 1)); System.out.println("NaN > 1 = " + (NAN > 1)); System.out.println("NaN < 1 = "+ (NAN 1)); System.out.println("NaN != 1 = " + (NAN != 1)); System.out.println("NaN == NaN = " + (NAN == NAN)); System.out.println("NaN > NaN = " + (NAN > NAN)); System.out.println("NaN < NaN = "+ (NAN NAN)); System.out.println("NaN != NaN = " + (NAN != NAN));
Давайте посмотрим на результат выполнения кода выше:
NaN == 1 = false NaN > 1 = false NaN < 1 = falseNaN != 1 = true NaN == NaN = false NaN > NaN = false NaN < NaN = falseNaN != NaN = true
Следовательно, мы не можем проверить наличие NaN , сравнивая с NaN с помощью «==» или «!=». На самом деле нам следует редко использовать операторы «==» или «!=» с типами float или double .
Вместо этого мы можем использовать выражение « x ! = х» . Это выражение возвращает true только для NAN.
Мы также можем использовать методы Float.isNaN и Double.isNaN для проверки этих значений . Это предпочтительный подход, поскольку он более читаем и понятен:
double x = 1; System.out.println(x + " is NaN = " + (x != x)); System.out.println(x + " is NaN = " + (Double.isNaN(x))); x = Double.NaN; System.out.println(x + " is NaN = " + (x != x)); System.out.println(x + " is NaN = " + (Double.isNaN(x)));
При запуске этого кода мы получим следующий результат:
1.0 is NaN = false 1.0 is NaN = false NaN is NaN = true NaN is NaN = true
4. Операции, производящие NaN
При выполнении операций с типами float и double нам нужно знать о значениях NaN .
Некоторые методы и операции с плавающей запятой производят значения NaN вместо создания исключения. Нам может понадобиться явно обрабатывать такие результаты.
Распространенным случаем, приводящим к нечисловым значениям, являются математически неопределенные числовые операции :
double ZERO = 0; System.out.println("ZERO / ZERO = " + (ZERO / ZERO)); System.out.println("INFINITY - INFINITY = " + (Double.POSITIVE_INFINITY - Double.POSITIVE_INFINITY)); System.out.println("INFINITY * ZERO = " + (Double.POSITIVE_INFINITY * ZERO));
Эти примеры приводят к следующему результату:
ZERO / ZERO = NaN INFINITY - INFINITY = NaN INFINITY * ZERO = NaN
Числовые операции, которые не дают результатов в действительных числах, также производят NaN:
System.out.println("SQUARE ROOT OF -1 = " + Math.sqrt(-1)); System.out.println("LOG OF -1 = " + Math.log(-1));
Эти заявления приведут к:
SQUARE ROOT OF -1 = NaN LOG OF -1 = NaN
Все числовые операции с NaN в качестве операнда дают в результате NaN :
System.out.println("2 + NaN = " + (2 + Double.NaN)); System.out.println("2 - NaN = " + (2 - Double.NaN)); System.out.println("2 * NaN = " + (2 * Double.NaN)); System.out.println("2 / NaN = " + (2 / Double.NaN));
И результат вышеизложенного:
2 + NaN = NaN 2 - NaN = NaN 2 * NaN = NaN 2 / NaN = NaN
Наконец, мы не можем присвоить null переменным типа double или float . Вместо этого мы можем явно присвоить NaN таким переменным, чтобы указать отсутствующие или неизвестные значения:
double maxValue = Double.NaN;
5. Вывод
В этой статье мы обсудили NaN и различные связанные с ним операции. Мы также обсудили необходимость обработки NaN при явном выполнении вычислений с плавающей запятой в Java.
Полный исходный код можно найти на GitHub .
- 1. Обзор
- 2. Что такое NaN ?
- 3. Сравнение с NaN
- 4. Операции, производящие NaN
- 5. Вывод
JavaScript: NaN
Некоторые операции с бесконечностями приводят к странному результату, например, деление бесконечности на бесконечность. В математике такая операция не имеет никакого числового эквивалента. В JavaScript вернется NaN .
Infinity / Infinity; // NaN
NaN — специальное значение «не число», которое обычно говорит о том, что была выполнена бессмысленная операция. Результатом практически любой операции, в которой участвует NaN , будет NaN .
NaN + 1; // NaN
NaN интересное значение, хотя оно обозначает «не число» — с точки зрения типов, оно является числом. Парадокс. NaN никогда не является желаемым значением и появляется только в результате ошибок. Если вы его встретили, то нужно отследить момент, в котором выполнилась операция, недопустимая для чисел, и поправить это место.
Задание
Выполните операцию, которая приводит к NaN, и распечатайте её результат на экран с помощью console.log() .
Упражнение не проходит проверку — что делать?
Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:
- Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Мой код отличается от решения учителя
Это нормально , в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.
В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Прочитал урок — ничего не понятно
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.
Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.
Обработка NaN и Infinite при вычислении в Java
В результате вычисления метод может возвратить значения NaN и Infinity, что в свою очередь может поломать программу в точке вызова. В моем понимании я должен обработать это внутри метода (Если NaN или Infinity, то возвратить ключ, который можно обработать вне метода). Вот в чём вопрос, что можно возвратить в качестве ключа или есть другой способ обработать данную ситуацию?
public static double raisedToPower(double a, double b) < double res = Math.pow(a, b); if (Double.isNaN(res) || Double.isInfinite(res)) < return key; >return res; >