Pregunta

Tengo un programa que intenta reducir una double abajo hasta el número deseado. La salida que se ve es NaN.

¿Qué significa NaN en Java?

¿Fue útil?

Solución

esta página :

  

"NaN" significa "no es un número". "Yaya"   se produce si un punto flotante   operación tiene algunos parámetros de entrada   que causa la operación para producir   un resultado no definido. Por ejemplo,   0.0 dividido por 0.0 no está definida aritméticamente. Tomando la raíz cuadrada de un   número negativo también es indefinido.

Otros consejos

medios NaN “no es un número” y es básicamente una representación de un valor de punto flotante especial en el IEE 754 flotante estándar punto . NaN generalmente significa que el valor es algo que no se puede expresar con un número de coma flotante válido.

Una conversión se traducirá en este valor, cuando el ser valor convertido es otra cosa, por ejemplo, cuando la conversión de una cadena que no representa un número.

medios NaN "no es un número" y es el resultado de las operaciones definidas en los números de coma flotante como por ejemplo dividiendo cero por cero. (Tenga en cuenta que mientras que la división de un no-cero número por cero también se suele sin definir en matemáticas, que no da lugar a NaN pero en el infinito positivo o negativo).

medios NaN "No es un número." Es un valor de punto flotante especial que significa que el resultado de una operación no se ha definido o no representable como un número real.

aquí para obtener una explicación más detallada de este valor.

NaN significa no un número. Se utiliza para significar cualquier valor que no está definido matemáticamente. Como dividir 0,0 por 0,0. Usted puede mirar aquí para obtener más información: https://web.archive.org/web/20120819091816/http://www.concentric.net/~ttwang/tech/javafloat.htm

Publica tu programa aquí si necesita más ayuda.

NaN = Not a Number.

Medios no un número. Es una representación común para un valor numérico imposible en muchos lenguajes de programación.

No es un tipo de Java, pero en JS y otros idiomas lo uso de "Not a Number", lo que significa una operación provocó que se convierta en no es un número válido.

Es, literalmente, significa "no es un número." Me algo sospechoso está mal con su proceso de conversión.

Visita la sección no es un número en esta referencia

No es un valor de punto flotante válido (por ejemplo, el resultado de la división por cero)

http://en.wikipedia.org/wiki/NaN

Minimal ejemplo runnable

Lo primero que hay que saber, es que el concepto de NaN se lleva a cabo directamente en el hardware de la CPU.

Todos los principales CPU modernas parecen seguir IEEE 754 que especifica formatos de punto flotante, y NaNs , que son valores especiales solo flotador, son parte de esa norma.

Por lo tanto, el concepto será el muy similar en cualquier idioma, incluyendo Java, que simplemente emite código de punto flotante directamente a la CPU.

Antes de continuar, es posible que desee leer primero las siguientes respuestas que he escrito:

Ahora un poco de acción de Java. La mayor parte de las funciones de interés que no están en el núcleo del lenguaje interior en vivo java.lang.Float .

Nan.java

import java.lang.Float;
import java.lang.Math;

public class Nan {
    public static void main(String[] args) {
        // Generate some NaNs.
        float nan            = Float.NaN;
        float zero_div_zero  = 0.0f / 0.0f;
        float sqrt_negative  = (float)Math.sqrt(-1.0);
        float log_negative   = (float)Math.log(-1.0);
        float inf_minus_inf  = Float.POSITIVE_INFINITY - Float.POSITIVE_INFINITY;
        float inf_times_zero = Float.POSITIVE_INFINITY * 0.0f;
        float quiet_nan1     = Float.intBitsToFloat(0x7fc00001);
        float quiet_nan2     = Float.intBitsToFloat(0x7fc00002);
        float signaling_nan1 = Float.intBitsToFloat(0x7fa00001);
        float signaling_nan2 = Float.intBitsToFloat(0x7fa00002);
        float nan_minus      = -nan;

        // Generate some infinities.
        float positive_inf   = Float.POSITIVE_INFINITY;
        float negative_inf   = Float.NEGATIVE_INFINITY;
        float one_div_zero   = 1.0f / 0.0f;
        float log_zero       = (float)Math.log(0.0);

        // Double check that they are actually NaNs.
        assert  Float.isNaN(nan);
        assert  Float.isNaN(zero_div_zero);
        assert  Float.isNaN(sqrt_negative);
        assert  Float.isNaN(inf_minus_inf);
        assert  Float.isNaN(inf_times_zero);
        assert  Float.isNaN(quiet_nan1);
        assert  Float.isNaN(quiet_nan2);
        assert  Float.isNaN(signaling_nan1);
        assert  Float.isNaN(signaling_nan2);
        assert  Float.isNaN(nan_minus);
        assert  Float.isNaN(log_negative);

        // Double check that they are infinities.
        assert  Float.isInfinite(positive_inf);
        assert  Float.isInfinite(negative_inf);
        assert !Float.isNaN(positive_inf);
        assert !Float.isNaN(negative_inf);
        assert one_div_zero == positive_inf;
        assert log_zero == negative_inf;
            // Double check infinities.

        // See what they look like.
        System.out.printf("nan            0x%08x %f\n", Float.floatToRawIntBits(nan           ), nan           );
        System.out.printf("zero_div_zero  0x%08x %f\n", Float.floatToRawIntBits(zero_div_zero ), zero_div_zero );
        System.out.printf("sqrt_negative  0x%08x %f\n", Float.floatToRawIntBits(sqrt_negative ), sqrt_negative );
        System.out.printf("log_negative   0x%08x %f\n", Float.floatToRawIntBits(log_negative  ), log_negative  );
        System.out.printf("inf_minus_inf  0x%08x %f\n", Float.floatToRawIntBits(inf_minus_inf ), inf_minus_inf );
        System.out.printf("inf_times_zero 0x%08x %f\n", Float.floatToRawIntBits(inf_times_zero), inf_times_zero);
        System.out.printf("quiet_nan1     0x%08x %f\n", Float.floatToRawIntBits(quiet_nan1    ), quiet_nan1    );
        System.out.printf("quiet_nan2     0x%08x %f\n", Float.floatToRawIntBits(quiet_nan2    ), quiet_nan2    );
        System.out.printf("signaling_nan1 0x%08x %f\n", Float.floatToRawIntBits(signaling_nan1), signaling_nan1);
        System.out.printf("signaling_nan2 0x%08x %f\n", Float.floatToRawIntBits(signaling_nan2), signaling_nan2);
        System.out.printf("nan_minus      0x%08x %f\n", Float.floatToRawIntBits(nan_minus     ), nan_minus     );
        System.out.printf("positive_inf   0x%08x %f\n", Float.floatToRawIntBits(positive_inf  ), positive_inf  );
        System.out.printf("negative_inf   0x%08x %f\n", Float.floatToRawIntBits(negative_inf  ), negative_inf  );
        System.out.printf("one_div_zero   0x%08x %f\n", Float.floatToRawIntBits(one_div_zero  ), one_div_zero  );
        System.out.printf("log_zero       0x%08x %f\n", Float.floatToRawIntBits(log_zero      ), log_zero      );

        // NaN comparisons always fail.
        // Therefore, all tests that we will do afterwards will be just isNaN.
        assert !(1.0f < nan);
        assert !(1.0f == nan);
        assert !(1.0f > nan);
        assert !(nan == nan);

        // NaN propagate through most operations.
        assert Float.isNaN(nan + 1.0f);
        assert Float.isNaN(1.0f + nan);
        assert Float.isNaN(nan + nan);
        assert Float.isNaN(nan / 1.0f);
        assert Float.isNaN(1.0f / nan);
        assert Float.isNaN((float)Math.sqrt((double)nan));
    }
}

GitHub aguas arriba .

Ejecutar con:

javac Nan.java && java -ea Nan

Salida:

nan            0x7fc00000 NaN
zero_div_zero  0x7fc00000 NaN
sqrt_negative  0xffc00000 NaN
log_negative   0xffc00000 NaN
inf_minus_inf  0x7fc00000 NaN
inf_times_zero 0x7fc00000 NaN
quiet_nan1     0x7fc00001 NaN
quiet_nan2     0x7fc00002 NaN
signaling_nan1 0x7fa00001 NaN
signaling_nan2 0x7fa00002 NaN
nan_minus      0xffc00000 NaN
positive_inf   0x7f800000 Infinity
negative_inf   0xff800000 -Infinity
one_div_zero   0x7f800000 Infinity
log_zero       0xff800000 -Infinity

Así que de esto aprendemos algunas cosas:

  • raro operaciones que no tienen ninguna consecuencia dar sensata NaN flotante:

    • 0.0f / 0.0f
    • sqrt(-1.0f)
    • log(-1.0f)

    generar una NaN.

    En C, en realidad es posible señales de petición a ser elevado en este tipo de operaciones con feenableexcept para detectarlos, pero no creo que se expone en Java: ¿por qué la división entera por cero 1 / 0 error dar, pero coma flotante 1 / 0.0 devuelve "Inf"?

  • operaciones extrañas que están en el límite de más o en menos infinito sin embargo damos + - infinito en lugar de NaN

    • 1.0f / 0.0f
    • log(0.0f)

    0.0 casi cae en esta categoría, pero es probable que el problema es que tampoco podía ir a más o menos infinito, por lo que se dejó como NaN.

  • si NaN es la entrada de una operación flotante, la salida también tiende a ser NaN

  • hay varios valores posibles para NaN 0x7fc00000, 0x7fc00001, 0x7fc00002, aunque x86_64 parece generar solamente 0x7fc00000.

  • NaN y el infinito tienen representación binaria similar.

    La ruptura de defraudado a algunos de ellos:

    nan          = 0x7fc00000 = 0 11111111 10000000000000000000000
    positive_inf = 0x7f800000 = 0 11111111 00000000000000000000000
    negative_inf = 0xff800000 = 1 11111111 00000000000000000000000
                                | |        |
                                | |        mantissa
                                | exponent
                                |
                                sign
    

    A partir de este Confirmamos lo IEEE754 especifica:

    • tanto Nan y tienen infinitos exponente == 255 (todos unos)
    • infinitos Tienes mantisa == 0. Hay, por tanto, sólo dos infinitos posibles: + y -, diferenciados por el bit de signo
    • NaN tiene mantisa! = 0. Por consiguiente, existen varias posibilidades, a excepción de mantisa == 0, que es el infinito
  • NaNs puede ser positivo o negativo (parte superior bit), aunque esto no tiene ningún efecto en las operaciones normales

Probado en Ubuntu 18.10 AMD64, OpenJDK 1.8.0_191.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top