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. Por 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 / double
zero 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 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 (==, <=, >=, <, >)
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
GO TO FULL VERSION