NaN в Java

NaN на Яве

1. обзор

Проще говоря,NaN - это значение числового типа данных, которое означает «не число».

В этом кратком руководстве мы объясним значениеNaN в Java и различные операции, которые могут создавать или задействовать это значение.

2. Что такоеNaN?

NaN usually indicates the result of invalid operations. Например, попытка разделить ноль на ноль является одной из таких операций.

We also use NaN for unrepresentable values. Квадратный корень из -1 является одним из таких случаев, поскольку мы можем описать значение (i) только в комплексных числах.

IEEE Standard for Floating-Point Arithmetic (IEEE 754) определяет значениеNaN. In Java, the floating-point types float and double implement this standard.

Java определяет константыNaN для типовfloat иdouble какFloat.NaN иDouble.NaN:

«A constant holding a Not-a-Number (NaN) value of type double. It is equivalent to the value returned by Double.longBitsToDouble(0x7ff8000000000000L).”

and:

«Константа, содержащая не-числовое (NaN) значение типа float. Это эквивалентно значению, возвращаемому Float.intBitsToFloat (0x7fc00000) ».

У нас нет такого типа констант для других числовых типов данных в Java.

3. Сравнение сNaN

При написании методов на Java, мы должны проверить, что ввод действителен и находится в ожидаемом диапазоне. ЗначениеNaN в большинстве случаев не является допустимым вводом. Следовательно, мы должны убедиться, что входное значение не является значениемNaN, и обработать эти входные значения соответствующим образом.

NaN нельзя сравнивать ни с одним значением плавающего типа. Это означает, что мы получимfalse для всех операций сравнения, включающихNaN (кроме «! =», Для которого мы получаемtrue).

Мы получаем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 = false
NaN != 1 = true
NaN == NaN = false
NaN > NaN = false
NaN < NaN = false
NaN != NaN = true

Следовательно,we cannot check for NaN by comparing with NaN using “==” or “!= “.. На самом деле, нам редко следует использовать операторы «==» или «! =» С типамиfloat илиdouble.

Вместо этого мы можем использовать выражение «x ! = x».. Это выражение возвращает истину только для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.

Some floating-point methods and operations produce NaN values instead of throwing an Exception. Нам может потребоваться явная обработка таких результатов.

Обычный случай, приводящий к нечисловым значениям, - этоmathematically undefined numerical operations:

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.

Полный исходный код можно найтиover on GitHub.