NaN em Java

NaN em Java

1. Visão geral

Simplificando,NaN é um valor de tipo de dados numérico que significa “não é um número”.

Neste tutorial rápido, explicaremos o valorNaN em Java e as várias operações que podem produzir ou envolver esse valor.

2. O que éNaN?

NaN usually indicates the result of invalid operations. Por exemplo, tentar dividir zero por zero é uma dessas operações.

We also use NaN for unrepresentable values. A raiz quadrada de -1 é um desses casos, pois podemos descrever o valor (i) apenas em números complexos.

OIEEE Standard for Floating-Point Arithmetic (IEEE 754) define o valor deNaN. In Java, the floating-point types float and double implement this standard.

Java define constantesNaN dos tiposfloatedouble comoFloat.NaNeDouble.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:

“Uma constante contendo um valor Não-numérico (NaN) do tipo float. É equivalente ao valor retornado por Float.intBitsToFloat (0x7fc00000). ”

Não temos esse tipo de constante para outros tipos de dados numéricos em Java.

3. Comparações comNaN

Ao escrever métodos em Java, devemos verificar se a entrada é válida e está dentro do intervalo esperado. O valorNaN não é uma entrada válida na maioria dos casos. Portanto, devemos verificar se o valor de entrada não é um valorNaNe tratar esses valores de entrada apropriadamente.

NaN não pode ser comparado com nenhum valor de tipo flutuante. Isso significa que obteremosfalse para todas as operações de comparação envolvendoNaN (exceto “! =” Para o qual obtemostrue).

Obtemostrue para “x != x” se e somente sex forNaN:

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));

Vamos dar uma olhada no resultado da execução do código acima:

NaN == 1 = false
NaN > 1 = false
NaN < 1 = false
NaN != 1 = true
NaN == NaN = false
NaN > NaN = false
NaN < NaN = false
NaN != NaN = true

Portanto,we cannot check for NaN by comparing with NaN using “==” or “!= “. Na verdade, raramente devemos usar os operadores “==” ou “! =” Com os tiposfloat oudouble.

Em vez disso, podemos usar a expressão “x ! = x”. Esta expressão retorna verdadeiro apenas paraNAN.

Também podemos usar os métodosFloat.isNaNeDouble.isNaN para verificar esses valores.. Esta é a abordagem preferida, pois é mais legível e compreensível:

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)));

Obteremos o seguinte resultado ao executar este código:

1.0 is NaN = false
1.0 is NaN = false
NaN is NaN = true
NaN is NaN = true

4. Produção de operaçõesNaN

Ao fazer operações envolvendo os tiposfloatedouble, precisamos estar cientes dos valoresNaN.

Some floating-point methods and operations produce NaN values instead of throwing an Exception. Podemos precisar lidar com tais resultados explicitamente.

Um caso comum que resulta em valores não numéricos é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));

Esses exemplos resultam na seguinte saída:

ZERO / ZERO = NaN
INFINITY - INFINITY = NaN
INFINITY * ZERO = NaN

Operações numéricas que não têm resultados em números reais também produzemNaN:

System.out.println("SQUARE ROOT OF -1 = " + Math.sqrt(-1));
System.out.println("LOG OF -1 = " +  Math.log(-1));

Essas declarações resultarão em:

SQUARE ROOT OF -1 = NaN
LOG OF -1 = NaN

Todas as operações numéricas comNaN como operando produzemNaN como resultado:

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));

E o resultado do exposto acima é:

2 + NaN = NaN
2 - NaN = NaN
2 * NaN = NaN
2 / NaN = NaN

Finalmente, não podemos atribuirnull adouble ou variáveis ​​do tipofloat. Em vez disso, podemos atribuir explicitamenteNaN a tais variáveis ​​para indicar valores ausentes ou desconhecidos:

double maxValue = Double.NaN;

5. Conclusão

Neste artigo, discutimosNaN e as várias operações que o envolvem. Também discutimos a necessidade de manipularNaN ao fazer cálculos de ponto flutuante em Java explicitamente.

O código-fonte completo pode ser encontradoover on GitHub.