John Squirrels
Nível 41
San Francisco

NaN em Java

Publicado no grupo Random-PT
Em Java, “NaN” significa “Not a Number”. Não é um tipo de exceção, surpreendentemente, o tipo de dados de NaN também é um número. Mas, muitas vezes, quando os programadores novatos o obtêm involuntariamente, eles o usam ainda mais em seus cálculos. Portanto, tipos de dados incompatíveis em Java, quando usados ​​juntos, podem causar um erro que pode ser lançado. Também é comumente visto que java.lang.ArithmeticException: / by zeroé considerado o mesmo que NaN. No entanto, Java trata ambos de forma diferente. Intrigante o suficiente? Para sua compreensão abrangente, dissecaremos como eles são diferentes um do outro. No final deste artigo, você aprenderá sobre as possíveis operações que produzem não um número (nan) e algumas maneiras fáceis de lidar com isso.

O que é NaN?

Então, o que é NaN? “NaN”, como muitos de vocês já imaginaram, é usado para representar “Não é um número” em Java. É um valor de ponto flutuante especial para denotar estouros e erros. É gerado quando um número de ponto flutuante é dividido por zero ou se a raiz quadrada de um número negativo é calculada. NaN em Java - 1Por exemplo, dê uma olhada no trecho a seguir.
public class NaN
{
    public static void main(String[]args)
    {
        System.out.println(0.0 / 0.0);	  //zero divided by zero
        System.out.println(Math.sqrt(-1)); //take sqrt of negative number
        System.out.println(10.0 % 0);      //taking mod by zero
    }
}
Saída
NaN
NaN
NaN
No trecho acima, você pode observar que o NaN é produzido como resultado de 3 operações simples:
  • Dividindo um float / doublezero por zero.
  • Tirando a raiz de um número negativo (Math.sqrt(-x)). Na matemática, tirar a raiz quadrada de um número negativo resulta em um número imaginário . Este caso é resolvido retornando NaN em Java.
  • Tomando mod de um número com zero, retornará o restante após dividir um valor por zero. Portanto, NaN é retornado.

Como o NaN é diferente do infinito positivo e negativo?

De acordo com a especificação IEEE 754, existem três valores especiais de ponto flutuante e duplo para lidar com os casos de limite:
  • infinito positivo
  • infinito negativo
  • NaN
O resultado da divisão de um número positivo por 0 é infinito positivo. Da mesma forma, o infinito negativo resulta da divisão de um número negativo por zero. Observe que todos os valores de ponto flutuante também são aplicáveis ​​ao tipo de dados double. A precisão limitada dos floats às vezes não é suficiente. No entanto, veremos como o NaN funciona para float e double em uma seção posterior.

O que é o método NaN()?

isNaN()é um dos métodos básicos em Java para verificar se é um valor NaN ou não. Como discutimos três casos acima, é hora de testar como o método isNaN() diferencia entre os valores +infinity , -infinity e NaN.
public class isNaN
{ public static void main(String[]args)
  {
    Double posInfinity = +2.0 / 0.0;
    Double negInfinity = -3.5 / 0.0;
    Double nanVal = 50 % 0.0;


    System.out.println ("+" + posInfinity + ".IsNaN() = " + posInfinity.isNaN());
    System.out.println ( negInfinity + ".IsNaN() = " + negInfinity.isNaN());
    System.out.println ( nanVal +  ".IsNaN() = " + nanVal.isNaN());
  }
}
Saída
+Infinity.IsNaN() = false
-Infinity.IsNaN() = false
NaN.IsNaN() = true

Como comparar valores de NaN?

Cada valor NaN é considerado distinto. Isso significa que nenhum NaN é igual a qualquer outro NaN. Por este princípio, se você comparar um valor com outro, o resultado é sempre negativo. Como NaN não é ordenado, uma comparação numérica envolvendo até mesmo um único NaN retorna falso. Java fornece Float.NaN e Double.NaN para campos constantes em ambas as classes para realizar comparações. Podemos diferenciá-los em dois cenários separados:
  • Verdadeiro: Somente em caso de desigualdade (!=)
  • Falso: Para todos os operandos de comparação (==, <=, >=, <, >)
Aqui está um exemplo de trabalho para vocês:
public class ComparingNaN
{ public static void main(String[] args)
  {
    // Comparing NaN values for Float constants
    System.out.println (Float.NaN != Float.NaN); // true
    System.out.println (Float.NaN == Float.NaN); // false
    System.out.println (Float.NaN < Float.NaN);  // false
    System.out.println (Float.NaN > Float.NaN);  // false
    System.out.println (Float.NaN <= Float.NaN); // false
    System.out.println (Float.NaN >= Float.NaN); // false

    // Comparing NaN values for Float constants
    System.out.println (Double.NaN != Double.NaN); // true
    System.out.println (Double.NaN == Double.NaN); // false
    System.out.println (Double.NaN < Double.NaN);  // false
    System.out.println (Double.NaN > Double.NaN);  // false
    System.out.println (Double.NaN <= Double.NaN); // false
    System.out.println (Double.NaN >= Double.NaN); // false
  }
}

Como gerar valores NaN?

Antes de encerrar, vamos ver alguns exemplos comuns de obtenção de Not a Number (nan).
public class GenerateNaNValues {
  static final float ZERO = 0;
  public static void main (String[]args)
  {
    System.out.println("ZERO / ZERO = " + (ZERO / ZERO));
    System.out.println("+INFINITY - INFINITY = " +
    (Float.POSITIVE_INFINITY + Float.NEGATIVE_INFINITY));
    System.out.println("-INFINITY * ZERO = " + (Float.NEGATIVE_INFINITY * ZERO));
    System.out.println("+INFINITY * ZERO = " + (Float.POSITIVE_INFINITY * ZERO));
    System.out.println("log10(-10) = " +  Math.log(-10));
    System.out.println("√-10 = " + Math.sqrt(-10));
    System.out.println("NaN + 10 = " + (Float.NaN + 10));
    System.out.println("NaN - 10 = " + (Float.NaN - 10));
    System.out.println("NaN * 10 = " + (Float.NaN * 10));
    System.out.println("NaN / 10 = " + (Float.NaN / 10));
    System.out.println("NaN + NaN = " + (Float.NaN + Float.NaN));
    System.out.println("NaN - NaN = " + (Float.NaN - Float.NaN));
    System.out.println("NaN * NaN = " + (Float.NaN * Float.NaN));
    System.out.println("NaN / NaN = " + (Float.NaN / Float.NaN));
  }
}
Saída:
ZERO / ZERO = NaN
+INFINITY - INFINITY = NaN
-INFINITY * ZERO = NaN
+INFINITY * ZERO = NaN
log10(-10) = NaN
√-10 = NaN
NaN + 10 = NaN
NaN - 10 = NaN
NaN * 10 = NaN
NaN / 10 = NaN
NaN + NaN = NaN
NaN - NaN = NaN
NaN * NaN = NaN
NaN / NaN = NaN

Conclusão

Depois de observar as inúmeras operações que produzem NaN, você deve estar familiarizado com ele agora. Pode confundir você inicialmente, mas não há nada complicado em lidar com isso. Desenvolver um pequeno hábito de verificar se um valor não é NaN em cálculos de ponto duplo/flutuante pode evitar muitos aborrecimentos. Mesmo se você esquecer isso inicialmente, está tudo bem. Você sempre pode consultar este artigo para solucionar problemas menores. A criação de código compilável e livre de erros de uma só vez vem após anos de experiência. Então, vamos colocar a mão na massa no código e construir algo ótimo!
Comentários
  • Populares
  • Novas
  • Antigas
Você precisa acessar para deixar um comentário
Esta página ainda não tem nenhum comentário