CodeGym /Blog Java /Random-ES /NaN en Java
Autor
Oleksandr Miadelets
Head of Developers Team at CodeGym

NaN en Java

Publicado en el grupo Random-ES
En Java, "NaN" significa "No es un número". No es un tipo de excepción, más bien sorprendentemente, el tipo de datos de NaN también es un número. Pero a menudo, cuando los programadores novatos lo obtienen sin querer, lo usan más en sus cálculos. Por lo tanto, los tipos de datos incompatibles en Java cuando se usan juntos pueden causar un error. También se ve comúnmente que java.lang.ArithmeticException: / by zerose considera lo mismo que NaN. Sin embargo, Java los trata a ambos de manera diferente. ¿Lo suficientemente desconcertante? Para su comprensión integral, analizaremos en qué se diferencian entre sí. Al final de este artículo, aprenderá sobre las posibles operaciones que producen no un número (nan) y algunas formas fáciles de manejarlas.

¿Qué es NaN?

Entonces, ¿qué es NaN? "NaN", como muchos de ustedes habrán adivinado, se usa para representar "No es un número" en Java. Es un valor de punto flotante especial para denotar desbordamientos y errores. Se genera cuando un número de punto flotante se divide por cero o si se calcula la raíz cuadrada de un número negativo. NaN en Java - 1Por ejemplo, eche un vistazo al siguiente fragmento.

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	
    }
}
Producción

NaN                                                                                                                                           
NaN                                                                                                                                           
NaN
En el fragmento anterior, puede observar que NaN se produce como resultado de 3 operaciones simples:
  • Dividir un float / doublecero con cero.
  • Tomando la raíz de un número negativo (Math.sqrt(-x)). En matemáticas, sacar la raíz cuadrada de un número negativo da como resultado un número imaginario . Este caso se trata devolviendo NaN en Java.
  • Tomando mod de un número con cero, devolverá el resto después de dividir un valor por cero. Por lo tanto, se devuelve NaN.

¿En qué se diferencia NaN del infinito positivo y negativo?

De acuerdo con la especificación IEEE 754, hay tres valores dobles y de punto flotante especiales para manejar los casos límite:
  • infinito positivo
  • infinito negativo
  • Yaya
El resultado de dividir un número positivo por 0 es infinito positivo. De manera similar, el infinito negativo se obtiene como resultado de dividir un número negativo por cero. Tenga en cuenta que todos los valores de coma flotante también se aplican al tipo de datos doble. La precisión limitada de los flotadores a veces no es suficiente. Sin embargo, veremos cómo funciona NaN tanto para float como para double en una sección posterior.

¿Qué es el método NaN()?

isNaN()es uno de los métodos básicos en Java para verificar si es un valor NaN o no. Como discutimos los tres casos anteriores, es hora de probar cómo el método isNaN() diferencia entre los valores +infinity , -infinity y 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());
  }
}
Producción

+Infinity.IsNaN() = false                                                                                                                       
-Infinity.IsNaN() = false                                                                                                                       
NaN.IsNaN() = true

¿Cómo comparar los valores de NaN?

Cada valor de NaN se considera distinto. Esto significa que ningún NaN es igual a ningún otro NaN. Por este principio, si comparas un valor con otro, el resultado siempre es negativo. Dado que NaN no está ordenado, una comparación numérica que involucre incluso un solo NaN devuelve falso. Java proporciona Float.NaN y Double.NaN para campos constantes en ambas clases para realizar comparaciones. Podemos diferenciarlos en dos escenarios separados:
  • Verdadero: Solo en caso de Desigualdad (!=)
  • Falso: para todos los operandos de comparación (==, <=, >=, <, >)
Aquí hay un ejemplo de trabajo para ustedes:

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
  }
}

¿Cómo generar valores NaN?

Antes de terminar, veamos algunos ejemplos comunes de obtener un No es un número (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));
  }
}
Producción:

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

Conclusión

Después de observar las numerosas operaciones que producen NaN, debe estar familiarizado con ellas ahora. Puede que te desconcierte inicialmente, pero no hay nada complicado para lidiar con esto. Al desarrollar un pequeño hábito de verificar si un valor no es NaN en los cálculos de punto flotante/doble, puede ahorrarle muchas molestias. Incluso si olvidas esto inicialmente, está totalmente bien. Siempre puede consultar este artículo para solucionar problemas menores. La creación de código compilable y sin errores de una sola vez se produce después de años de experiencia. ¡Así que ensuciémonos las manos con el código y construyamos algo genial!
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION