Pergunta

Achei que MIN_NORMAL era um valor que você poderia adicionar a um duplo "normal" e o número mudaria.Por exemplo.adicione Double.MIN_NORMAL a 0,1d e você obterá um valor diferente de 0,1d, porém meu entendimento está errado:

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

O que produz:

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

Alguém, por favor, explique o que está indo contra minha lógica aqui, que mesmo se eu adicionar MIN_NORMAL vezes 1e50d, ainda obterei o mesmo número.

Verifiquei as representações binárias e 1 * Double.MIN_NORMAL é diferente de 2 * Double.MIN_NORMAL, mas subtraí-las de qualquer coisa, exceto zero, não altera o número original.

Foi útil?

Solução

MIN_NORMAL é, como diz o Javadoc, apenas o menor normalizado double valor.Mas isso não significa que seja algo como 1 para inté:Para valores de ponto flutuante, simplesmente existe não "eps" padrão que você pode adicionar para alterar o próximo valor representável - o "eps" sempre depende do expoente do valor de ponto flutuante fornecido.É por isso que eles são chamados flutuando pontos, no final :)

No entanto, Java 1.6+ fornece Math.nextAfter() que retorna, para qualquer dado double, o próximo ou anterior representável double.

Em versões mais antigas do Java, você sempre pode mexer Double.doubleToLongBits(), aumentando ou diminuindo seu resultado e convertendo de volta por Double.longBitsToDouble();isso dá a você o próximo ou anterior representável double valor -- na maioria dos casos:existem alguns casos especiais (NaN, valores infinitos), então isso não é recomendado para iniciantes em ponto flutuante :)

Outras dicas

Double tem uma precisão limitada.MIN_NORMAL é 2e-1022.Ele será descartado, a menos que o número ao qual você o adicionou também esteja próximo de 2e-1000.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top