Question

Je pensais que MIN_NORMAL était une valeur que vous pouviez ajouter à un double "normal" et le nombre changerait.Par exemple.ajoutez Double.MIN_NORMAL à 0,1d et vous obtenez une valeur différente de 0,1d, mais ma compréhension est fausse :

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

Ce qui produit :

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

Quelqu'un explique ici ce qui va à l'encontre de ma logique, que même si j'ajoute MIN_NORMAL fois 1e50d, j'obtiens toujours le même nombre.

J'ai vérifié les représentations binaires et 1 * Double.MIN_NORMAL est différent de 2 * Double.MIN_NORMAL, mais les soustraire de tout sauf zéro ne change pas le nombre d'origine.

Était-ce utile?

La solution

MIN_NORMAL est, comme le dit le Javadoc, seulement le plus petit normalisé double valeur.Mais cela ne veut pas dire que c'est quelque chose comme 1 pour ints :Pour les valeurs à virgule flottante, il existe simplement Non "eps" standard que vous pouvez ajouter pour passer à la valeur représentable suivante - le "eps" dépend toujours de l'exposant de la valeur à virgule flottante donnée.C'est pourquoi on les appelle flottant des points, au final :)

Cependant, Java 1.6+ fournit Math.nextAfter() qui renvoie, pour tout donné double, le représentable suivant ou précédent double.

Sur les anciennes versions de Java, vous pouvez toujours jouer avec Double.doubleToLongBits(), incrémentant ou décrémentant son résultat, et reconvertissant en Double.longBitsToDouble();cela vous donne le représentable suivant ou précédent double valeur -- dans la plupart des cas:il existe quelques cas particuliers (NaN, valeurs infinies), donc cela n'est pas recommandé aux débutants en virgule flottante :)

Autres conseils

Le double a une précision limitée.Min_normal est 2E-1022.Il sera chuté à moins que le numéro que vous ajoutez est également dans le ballpark de 2E-1000.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top