Ce n'est pas une question en double car j'ai lu la question précédente.
Quelqu'un peut-il m'aider à comprendre how float values are stored in the memory
.
Mon doute est ici que les valeurs flottantes contiennent '.'
(for example 3.45
) comment le '.'
sera représenté dans la mémoire?
Quelqu'un peut-il me préciser un schéma?
Le point décimal n'est stocké explicitement nulle part; c'est un problème d'affichage.
L'explication suivante est une simplification; Je laisse de côté beaucoup de détails importants et mes exemples ne sont pas censés représenter une plate-forme réelle. Cela devrait vous donner une idée de la façon dont les valeurs à virgule flottante sont représentées dans la mémoire et des problèmes qui leur sont associés, mais vous voudrez trouver des sources plus fiables comme Ce que tout informaticien devrait savoir sur l'arithmétique à virgule flottante =.
Commencez par représenter une valeur à virgule flottante dans une variante de la notation scientifique, en utilisant la base 2 au lieu de la base 10. Par exemple, la valeur 3.14159 peut être représentée comme
0,7853975 * 22
0,7853975 est la signification , alias la mantisse; c'est la partie du numéro contenant les chiffres significatifs. Cette valeur est multipliée par la base 2 élevée à la puissance de 2 pour obtenir 3,14159.
Les nombres à virgule flottante sont codés en stockant la significande et l'exposant (avec un bit de signe).
Une disposition 32 bits typique ressemble à ceci:
3 32222222 22211111111110000000000
1 09876543 21098765432109876543210
+-+--------+-----------------------+
| | | |
+-+--------+-----------------------+
^ ^ ^
| | |
| | +-- significand
| |
| +------------------- exponent
|
+------------------------ sign bit
Comme les types entiers signés, le bit de poids fort indique le signe; 0 indique une valeur positive, 1 indique une valeur négative.
Les 8 bits suivants sont utilisés pour l'exposant. Les exposants peuvent être positifs ou négatifs, mais au lieu de réserver un autre bit de signe, ils sont codés de sorte que 10000000 représente 0, donc 00000000 représente -128 et 11111111 représente 127.
Les bits restants sont utilisés pour la signification. Chaque bit représente une puissance négative de 2 en partant de la gauche, donc:
01101 = 0 * 2-1 + 1 * 2-2 + 1 * 2-3 + 0 * 2-4 + 1 * 2-5 = 0,25 + 0,125 + 0,03125 = 0,40625
Certaines plates-formes supposent un bit de tête "caché" dans la significande qui est toujours défini sur 1, donc les valeurs dans la significande sont toujours comprises entre [0,5, 1). Cela permet à ces plates-formes de stocker des valeurs avec une précision légèrement supérieure (plus d'informations ci-dessous). Mon exemple ne fait pas ça.
Donc, notre valeur de 3,14159 serait représentée comme quelque chose comme
0 10000010 11001001000011111100111 ^ ^ ^ | | | | | + --- significande = 0,7853975 ... | | | + ------------------- exposant = 2 (130 - 128) | + ---------- --------------- signe = 0 (positif) valeur = -1(signe) * 2 (exponent) * (significande) valeur = -1 * 22 * 0,7853975 ... Valeur = 3,14159 ...
Maintenant, quelque chose que vous remarquerez si vous additionnez tous les bits dans la signification, c'est qu'ils ne totalisent pas 0.7853975; ils sortent en fait à 0,78539747. Il n'y a pas assez de bits pour stocker la valeur exactement ; nous ne pouvons stocker qu'une approximation. Le nombre de bits dans le significand détermine la précision , ou le nombre de chiffres significatifs que vous pouvez stocker. 23 bits nous donne environ 6 chiffres décimaux de précision. Les types à virgule flottante 64 bits offrent suffisamment de bits dans la signification pour donner environ 12 à 15 chiffres de précision. Mais sachez qu'il existe des valeurs qui ne peuvent pas être représentées exactement, peu importe le nombre de bits que vous utilisez. Tout comme les valeurs comme 1/3 ne peuvent pas être représentées dans un nombre fini de chiffres décimaux, les valeurs comme 1/10 ne peuvent pas être représentées dans un nombre fini de bits. Comme les valeurs sont approximatives, les calculs avec elles sont également approximatifs et les erreurs d'arrondi s'accumulent.
Le nombre de bits de l'exposant détermine la plage (les valeurs minimales et maximales que vous pouvez représenter). Mais à mesure que vous vous rapprochez de vos valeurs minimale et maximale, la taille de l'écart entre les valeurs représentables augmente. Autrement dit, si vous ne pouvez pas représenter exactement des valeurs comprises entre 0,785397 et 0,785398, vous ne pouvez pas non plus représenter exactement des valeurs comprises entre 7,85397 et 7,85398, ou des valeurs comprises entre 78,5397 et 78,5398, ou des valeurs comprises entre 785397,0 et 785398,0. Soyez prudent lorsque vous multipliez de très grands nombres (en termes de magnitude) par de très petits nombres.
Le .
n'est pas stocké du tout. Tout d'abord, vous devez comprendre la notation d'ingénierie, qui a un facteur de précision fixe et un exposant entier: 1
est 1,0 · 10 = 1.0E0
, 2 est 2.0E0
, 10 est 1.0E1
etc. Ceci permet une notation très courte des grands nombres. Un milliard est 1.0E9
. Le facteur avant E
est généralement noté comme un nombre à précision fixe: 1.00000E9
. Il en résulte que le nombre n milliard et un = 1 000 000 001 et n milliard sont tous deux les mêmes dans cette notation, lorsque la précision n'est pas assez grande. Notez également que le facteur n'a jamais besoin d'un zéro de tête. Au lieu de cela, l'exposant peut être décrémenté jusqu'à ce que ce ne soit plus le cas.
En mémoire, un nombre à virgule flottante est représenté de la même manière: un bit a le signe, certains bits forment le facteur comme un nombre à précision fixe ("mantisse"), les bits restants forment l'exposant. Des différences importantes par rapport à la notation d'ingénierie de base 10 sont que, bien sûr, l'exposant a maintenant la base 2. La taille exacte de chaque partie dépend de la norme à virgule flottante exacte que vous utilisez.