Les ordinateurs stockent la plupart des nombres non entiers sous forme de virgule flottante : un signe, un exposant et une fraction, comme la notation scientifique écrit 1,6 × 10^-1. La norme IEEE 754 fixe les détails, si bien qu'un double se comporte de la même façon sur toutes les machines. Le prix à payer : seuls certains nombres sont stockés exactement. Inspectez n'importe quelle valeur avec le convertisseur de flottants IEEE 754 et comparez les principaux types dans Float vs Double vs Decimal.
Signe, exposant, fraction
Un nombre binaire à virgule flottante vaut (-1)^signe × 1.fraction × 2^(exposant - biais). Le 1. initial est implicite (un « bit caché »), si bien qu'un double obtient 53 bits de précision à partir de 52 bits de fraction stockés.
Exemple résolu : 0,1
En double précision, 0,1 est stocké sous la forme des 64 bits 3fb999999999999a (hexadécimal) : signe 0, exposant 1019 (soit 1019 - 1023 = -4) et fraction 0x999999999999a, ce qui représente environ 1,6 × 2^-4. Comme 1/10 n'a pas de développement binaire fini, la valeur stockée est le double le plus proche :
0.1000000000000000055511151231257827021181583404541015625
La valeur en simple précision 3dcccccd est 0.100000001490116119384765625. Aucune n'égale 0,1 ; l'erreur est trop petite pour se voir à l'affichage ordinaire.
Les formats courants
| Format | Bits | Bits d'exposant | Bits de fraction | Plus grande valeur | Plus petit normal | Plus petit dénormalisé | Écart à 1,0 |
|---|---|---|---|---|---|---|---|
| demi (binary16) | 16 | 5 | 10 | 65,504 | 6,10 × 10^-5 | 5,96 × 10^-8 | 9,77 × 10^-4 |
| simple (binary32) | 32 | 8 | 23 | 3,4028235 × 10^38 | 1,1754944 × 10^-38 | 1,4 × 10^-45 | 1,19 × 10^-7 |
| doble (binary64) | 64 | 11 | 52 | 1,7976931348623157 × 10^308 | 2,2250738585072014 × 10^-308 | 4,9 × 10^-324 | 2,22 × 10^-16 |
Valeurs spéciales
- Le zéro a un signe :
+0et-0sont égaux à la comparaison mais diffèrent dans certaines opérations (1 / -0vaut-infini). - L'infini résulte d'un dépassement ou d'une division par zéro. NaN (not a number) résulte de
0 / 0ou desqrt(-1), etNaNn'est égal à rien, pas même à lui-même. - Les nombres dénormalisés comblent l'intervalle entre zéro et le plus petit nombre normal, au prix d'une précision réduite, pour un dépassement vers le bas progressif.
Surprises d'arrondi et bonnes habitudes
- Additionner dix fois 0,1 donne
0.9999999999999999, pas 1. - L'addition n'est pas associative :
1e16 + 1 - 1e16vaut0, mais1e16 - 1e16 + 1vaut1, car l'écart près de 10^16 est de 2. - Ne comparez jamais avec
==. Testezabs(a - b) <= tolérance, adaptée à la taille des valeurs. - Additionnez de nombreux nombres du plus petit au plus grand, ou utilisez la sommation compensée.
- Pour l'argent, utilisez des entiers (centimes) ou un type décimal.