web-dev-qa-db-fra.com

Comment NaN et Infinity d'un float ou double sont-ils stockés en mémoire?

Si je comprends bien Java stockera un flottant en mémoire sous la forme d'un entier 32 bits avec les propriétés suivantes:

  • Le premier bit est utilisé pour déterminer le signe
  • Les 8 bits suivants représentent l'exposant
  • Les 23 derniers bits sont utilisés pour stocker la fraction

Cela ne laisse aucun morceau de rechange pour les trois cas spéciaux:

  • NaN
  • Infini positif
  • Infini négatif

Je peux deviner que 0 négatif pourrait être utilisé pour stocker l'un d'eux.

Comment sont-ils réellement représentés en mémoire?

39
roblovelock

Java spécifie que les nombres à virgule flottante suivent la norme IEEE 754 .

Voici comment il est stocké:

  • bit 0: bit de signe
  • bits 1 à 11: exposant
  • bits 12 à 63: fraction

Maintenant, j'ai exécuté la méthode ci-dessous avec différentes valeurs doubles:

public static void print(double d){
    System.out.println(Long.toBinaryString(Double.doubleToRawLongBits(d)));
}

J'ai exécuté avec ces valeurs:

print(Double.NaN);
print(Double.NEGATIVE_INFINITY);
print(Double.POSITIVE_INFINITY);
print(-Double.MAX_VALUE);
print(Double.MAX_VALUE);

Et obtenu la sortie suivante pour les valeurs ci-dessus (formatée pour la lisibilité):

 NaN: 0111111111111000000000000000000000000000000000000000000000000000
-Inf: 1111111111110000000000000000000000000000000000000000000000000000
+Inf: 0111111111110000000000000000000000000000000000000000000000000000
-Max: 1111111111101111111111111111111111111111111111111111111111111111
+Max: 0111111111101111111111111111111111111111111111111111111111111111

Wikipedia explique que lorsque le champ exposant est tout-bits-1, le nombre est Inf ou NaN. Inf a tous les bits de la mantisse zéro; NaN a au moins un bit dans la mantisse mis à 1. Le bit de signe conserve sa signification normale pour Inf mais n'est pas significatif pour NaN. Double.NaN De Java est une valeur particulière qui sera interprétée comme NaN, mais il y en a 253-3 autres.

56
Darshan Mehta

De ici :

Q. Comment le zéro, l'infini et le NaN sont-ils représentés à l'aide d'IEEE 754?

A. En définissant tous les bits d'exposant sur 1. Infini positif = 0x7ff0000000000000 (tous les bits d'exposant 1, bit de signe 0 et tous les bits de mantisse 0), infini négatif = 0xfff0000000000000 (tous les bits d'exposant 1, bit de signe 1 et tous les bits de mantisse 0) , NaN = 0x7ff8000000000000 (tous les bits d'exposant 1, au moins un bit de mantisse défini). Zéro positif = tous les bits 0. Zéro négatif = tous les bits 0, sauf le bit de signe qui est 1.

Consultez également les Javadocs sur NAN, Positive Infinity et Negative Infinity .

17
Rahul Tripathi

Comme décrit dans Wikipedia , l'exposant avec tous les bits mis à 1 est utilisé pour identifier ces nombres. Le champ de fraction défini sur 0 est utilisé pour identifier l'infini (positif ou négatif, comme identifié par le signe), et un champ de fraction non nul identifie une valeur NaN.

5
yole

Java utilise la virgule flottante IEEE 754.

La plupart des nombres sont exprimés dans un format mantisse exposant-signe avec la mantisse ayant un interligne implicite 1.

Les valeurs extrêmes du champ exposant (tous les zéros et tous les uns) ne sont pas utilisées comme valeurs d'exposant normales. Au lieu de cela, ils sont utilisés pour représenter des cas spéciaux.

Tous les zéros de l'exposant feild sont utilisés pour représenter des nombres (y compris le zéro positif et négatif) qui sont trop petits pour être représentés dans le format normal.

Tous ceux de l'exposant sont utilisés pour représenter des valeurs spéciales. Si tous les bits de la mantisse sont nuls, la valeur est plus ou moins l'infini (signe indiqué par le bit de signe). Sinon, la valeur est NaN.

3
plugwash

Tout d'abord, nous devons apprendre comment le nombre est représenté comme le point flottant et double dans la mémoire.

Le numéro général est de la forme: 1.M * 2 ^ e.

(où le M est appelé mantisse et le e est l'exposant dans l'excès-127)

en virgule flottante

Le MSB (bit le plus significatif) est utilisé comme bit de signe et le nombre de bits de 23 à 31 est utilisé pour la valeur exponentielle sous la forme d'un excès de 127 et le nombre de bits de 0 à 30 est utilisé pour stocker la mantisse.

en double

Le MSB (bit le plus significatif) est utilisé comme bit de signe et le nombre de bits de 52 à 63 est utilisé pour la valeur exponentielle sous la forme d'un excès de 127 et le nombre de bits de 0 à est utilisé pour stocker la mantisse.

alors maintenant nous sommes en mesure de comprendre la représentation NaN, Infinity dans le flotteur ou le double.

NaN (Pas un nombre)

Dans la représentation du NaN, tous les bits d'exposant sont 1 et les bits de Mantissa peuvent être n'importe quoi et peu importe qu'il soit en flottant ou décimal.

Infini

Dans la représentation de l'infini, tous les bits d'exposant sont 1 et les bits de Mantissa sont 0 et peu importe qu'il soit en flottant ou décimal. Le infini positif est représenté de la même manière que ci-dessus mais le bit de signe est 0 et le infini négatif est également représenté de la même manière mais le bit de signe est ici 1.

0
Rahul Dhawan