Pregunta

Pensé que MIN_NORMAL era un valor que podías agregar a un doble "normal" y el número cambiaría.P.ej.agregue Double.MIN_NORMAL a 0.1d y obtendrá un valor diferente de 0.1d, sin embargo, mi entendimiento es incorrecto:

public static void test(double val) {
    if (val == (val - Double.MIN_NORMAL*1e50d))
        System.out.printf("val == (val - Double.MIN_NORMAL*1e50d) for val=%.20f\n", val);
    else
        System.out.printf("val != (val - Double.MIN_NORMAL*1e50d) for val=%.20f\n", val);
}

Que produce:

test(0.0d);
> val != (val - Double.MIN_NORMAL*1e50d) for val=0.00000000000000000000

test(1.0d);
> val == (val - Double.MIN_NORMAL*1e50d) for val=1.00000000000000000000

test(0.1d);
> val == (val - Double.MIN_NORMAL*1e50d) for val=0.10000000000000000000

Que alguien explique qué va en contra de mi lógica aquí, que incluso si sumo MIN_NORMAL multiplicado por 1e50d, sigo obteniendo el mismo número.

Revisé las representaciones binarias y 1 * Double.MIN_NORMAL es diferente de 2 * Double.MIN_NORMAL, pero restarlas de cualquier valor excepto cero no cambia el número original.

¿Fue útil?

Solución

MIN_NORMAL es, como dice el Javadoc, sólo el más pequeño normalizado double valor.Pero eso no significa que sea algo como 1 para ints:Para valores de punto flotante, simplemente existe No "eps" estándar que puede agregar para cambiar al siguiente valor representable; los "eps" siempre dependen del exponente del valor de punto flotante dado.Por eso se llaman flotante puntos, al final :)

Sin embargo, Java 1.6+ proporciona Math.nextAfter() que devuelve, para cualquier dado double, el siguiente o anterior representable double.

En versiones anteriores de Java, siempre puedes trastear con Double.doubleToLongBits(), incrementando o disminuyendo su resultado y volviendo a convertir por Double.longBitsToDouble();esto te da el representable siguiente o anterior double valor -- en la mayoría de los casos:Hay algunos casos especiales (NaN, valores infinitos), por lo que no se recomienda esto para principiantes en punto flotante :)

Otros consejos

Double tiene una precisión limitada.Min_Normal es 2E-1022.Se reducirá a menos que el número que lo agregue a la que lo agregue también está en el estadio Ballpark de 2E-1000.

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