Différence entre Double.MIN_NORMAL et Double.MIN_VALUE?

Puis-je savoir quelle est la différence entre Double.MIN_NORMAL (introduit en 1.6) et Double.MIN_VALUE ?

JavaDoc de Double.MIN_NORMAL :

Une constante contenant la plus petite valeur normale positive de type double , 2 -1022

JavaDoc de Double.MIN_VALUE :

Une constante contenant la plus petite valeur non nulle positive du type double , 2 -1074

La réponse se trouve dans la spécification IEEE de la représentation en virgule flottante :

Pour le format unique, la différence entre un nombre normal et un nombre inférieur à la normale est que le bit principal du significande (le bit à gauche du point binary) d’un nombre normal est 1, tandis que le bit principal du significande d’une valeur inférieure à la normale le nombre est 0. Les nombres sous-normaux à format unique ont été appelés nombres dénormalisés à format unique dans la norme IEEE 754.

En d’autres termes, Double.MIN_NORMAL est le plus petit nombre possible que vous pouvez représenter, à condition que vous ayez un 1 devant le point binary (ce que l’on appelle un point décimal dans un système décimal). Alors que Double.MIN_VALUE est fondamentalement le plus petit nombre que vous pouvez représenter sans cette contrainte.

Tldr:

Double.MIN_NORMAL donne le plus petit nombre normal positif IEEE-754 binary64 (également appelé nombre normalisé). Cela équivaut à 2 -1022 , soit environ 2,225 × 10 -308 .

Double.MIN_VALUE donne le plus petit nombre IEEE-754 binary64 positif (également appelé nombre dénormalisé ou subnormal). Cela équivaut à 2 -1074 , soit environ 4,94 × 10 -324 . (C’est aussi le numéro donné par Double.Epsilon .NET).

Tsdr:

Pour comprendre pourquoi ces chiffres sont ce qu’ils sont et quelle est la différence entre eux, nous devrons regarder plus loin. (Lisez aussi la réponse de Bosonix.)

Considérons la représentation binary d’un format binary64 IEEE-754:

 s_eee_eeee_eeee_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm 

Les valeurs IEEE-754 binary64 sont calculées en tant que telles:

  • Si e est supérieur à 0 et inférieur à 2047 (2047 est 111_1111_1111 en binary),

    alors la valeur est égale à (-1) s × 2 e-1023 × (1 + m × 2 -52 ). (Ce sont les nombres normaux.)

  • Si e est égal à 0,

    alors la valeur est égale à (-1) s × 2 (e + 1) -1023 × (0 + m × 2 -52 ). (Outre zéro, ce sont les nombres inférieurs à la normale.)

  • Si e est égal à 2047 et m est égal à 0,

    alors la valeur est égale à (-1) s × infini .

  • Si e est égal à 2047 et m n’est pas égal à 0,

    alors la valeur est égale à NaN. (Fait sans rapport: il y a donc 2 × (2 52 – 1) représentations de bits différentes pour NaN ; cf. doubleToRawLongBits .)

Par conséquent, le plus petit nombre normal binary64 IEEE-754 positif est égal à:

(-1) 0 × 2 1-1023 × (1 + 0 × 2 -52 )

= 2 -1022

Et le plus petit nombre subnormal IEEE-754 binary64 positif est égal à:

(-1) 0 × 2 (0 + 1) -1023 × (0 + 1 × 2 -52 )

= 2 -1022 × 2 -52

= 2 -1074

Pour simplifier, l’explication ne prendra en compte que les nombres positifs.

L’espacement maximal entre deux nombres à virgule flottante normalisés adjacents ‘x1’ et ‘x2’ est 2 * epsilon * x1 (les nombres à virgule flottante normalisés ne sont pas régulièrement espacés, ils sont espacés logarithmiquement). Cela signifie que, lorsqu’un nombre réel (c’est-à-dire le nombre “mathématique”) est arrondi à un nombre à virgule flottante, l’ erreur relative maximale est epsilon , qui est une constante appelée machine epsilon ou unité arrondie . 2 ^ -52 (valeur approximative 2,22e-16).

Les nombres à virgule flottante inférieurs à Double.MIN_NORMAL sont appelés subnormals et remplissent également l’espace entre 0 et Double.MIN_NORMAL . Cela signifie que les calculs impliquant des sous-normales peuvent conduire à des résultats moins précis. L’utilisation de sous-normales permet à un calcul de perdre de la précision plus lentement lorsque le résultat est faible.