Aussi disponible en : English · Español · Português · العربية
Convertisseur de virgule flottante IEEE 754
Voyez le signe, l'exposant et la mantisse de n'importe quel nombre, et la valeur décimale exacte que la machine conserve plutôt que celle, arrondie, qu'elle affiche.
Qu'est-ce que l'IEEE 754 ?
L'IEEE 754 est la norme qui dit comment les ordinateurs stockent les nombres à virgule. À peu près tout l'utilise : un nombre JavaScript, un nombre JSON, une cellule de tableur, un double en C, un flottant de base de données. La disposition tient en trois champs sur un nombre fixe de bits — un bit de signe, puis un exposant, puis une fraction — et la valeur encodée est la fraction multipliée par deux élevé à l'exposant.
Comme l'exposant est une puissance de deux, le format ne peut stocker que les fractions dont le dénominateur est une puissance de deux. Un demi, un quart, un huitième : exacts. Un dixième : non, de la même façon qu'un tiers n'a pas d'écriture décimale exacte. Le nombre que vous avez saisi et celui que la machine a gardé ne sont donc généralement pas le même, et c'est cet écart que montre cette page.
Ce que presque aucun outil n'affiche, c'est la valeur exacte. Les programmes affichent les flottants avec le plus court décimal qui se relirait comme la même valeur : 0,1 s'affiche donc 0,1 et paraît correct. La valeur réellement stockée est 0,1000000000000000055511151231257827021181583404541015625. Ce n'est pas un arrondi de la valeur stockée — c'est la valeur stockée, écrite en entier.
Comment l'utiliser
- Saisissez un nombre. Ce que vous écririez dans du code, y compris la notation exponentielle comme 5e-324. Les boutons couvrent les cas qui montrent quelque chose d'intéressant.
- Lisez les bits. Signe, exposant et fraction ont chacun leur couleur, l'hexadécimal figure en dessous. Le panneau suivant indique si la valeur est normale, dénormalisée, nulle, infinie ou NaN.
- Comparez ce que vous avez saisi à ce qui est stocké. La valeur décimale exacte s'affiche en entier, avec une note disant si votre nombre a survécu. Passez en 32 bits pour voir le même nombre stocké sur deux fois moins de bits.
Pourquoi 0,1 + 0,2 ne fait pas 0,3
C'est l'exemple que tout le monde rencontre en premier, et l'explication habituelle — la virgule flottante est imprécise — est vraie mais s'arrête une étape trop tôt. Le point intéressant est que les trois nombres sont déjà faux avant la moindre addition. Stockés comme doubles, 0,1 est légèrement au-dessus d'un dixième, 0,2 légèrement au-dessus d'un cinquième, et 0,3 légèrement au-dessous de trois dixièmes. Saisissez-les tour à tour dans l'outil ci-dessus et vous pourrez lire les trois.
Additionnez les deux premiers et le résultat exact est 0,3000000000000000444089209850062616169452667236328125. Le double le plus proche de trois dixièmes est une autre valeur, et elles ne sont pas seulement proches : elles sont adjacentes. Aucun nombre représentable ne se glisse entre les deux, si bien que la somme rate d'un écart aussi petit que le format sait l'exprimer à cette échelle — et cela suffit à rendre la comparaison fausse.
Le même mécanisme explique le conseil qu'on vous a sûrement donné à propos de l'argent. Rien dont le dénominateur porte un facteur cinq ne survit — un dixième, un centime, un cinquième —, c'est-à-dire toute somme d'argent que l'on écrit. C'est aussi pourquoi comparer deux flottants par égalité n'est pas fiable en général, alors que comparer un demi ou un quart est parfaitement sûr.
Ce que cela rend visible
Les entiers sont exacts jusqu'à un certain point, puis cessent de l'être. Tout entier est stocké parfaitement jusqu'à deux puissance cinquante-trois ; le suivant, 9007199254740993, n'a pas de représentation et retombe sur son voisin, si bien qu'un programme manipulant de grands identifiants peut en fusionner deux sans rien signaler. Saisissez-le ci-dessus et l'outil renvoie 9007199254740992. En 32 bits le plafond est bien plus bas : 16777217 ne tient déjà plus et revient sous la forme 16777216.
Les valeurs ne sont pas régulièrement espacées. L'écart entre voisins double à chaque puissance de deux : environ deux fois dix puissance moins seize près de 1, exactement 1 à deux puissance cinquante-deux, et exactement 2 juste au-dessus — autrement dit les entiers impairs cessent d'exister. Entre 1 et 2 il y a deux puissance cinquante-deux valeurs distinctes ; entre 2 et 4, le même nombre, réparti sur une distance deux fois plus grande.
Les très petits nombres changent de comportement plutôt que de disparaître. Sous la plus petite valeur normale, le format abandonne le 1 de tête implicite et laisse la précision se dégrader progressivement au lieu de sauter à zéro. Ce sont les nombres dénormalisés, et le plus petit vaut deux puissance moins 1074, dont la valeur décimale exacte compte 1076 caractères — que l'outil affiche sans broncher.
Et il y a deux zéros. Le zéro négatif possède son propre motif de bits, se compare comme égal au positif, et se distingue malgré tout : diviser un par lui donne moins l'infini. Le panneau des bits montre la différence que le test d'égalité dissimule.
Comment cela a été vérifié, et ce que cela ne couvre pas
Les valeurs décimales exactes sont calculées uniquement en arithmétique entière : aucune virgule flottante n'intervient pour décrire la virgule flottante, ce qui serait circulaire. Une valeur stockée est une mantisse entière multipliée par une puissance de deux, et multiplier en haut et en bas par la puissance de cinq correspondante en fait un décimal qui se termine ; l'écriture est donc toujours finie et toujours exacte.
Chaque motif de bits et chaque valeur exacte a été comparé à la bibliothèque standard de Python sur plus de deux mille nombres couvrant tout le domaine, dénormalisés, les deux zéros, les deux infinis et les extrêmes compris. Le module decimal de Python donne la valeur exacte d'un double et non une approximation, ce qui en fait un oracle exact et pas seulement indépendant.
Ce qui n'est pas couvert : les doubles sur 64 bits et les flottants sur 32, mais ni les formats sur 16 et 128 bits ni les encodages décimaux que la norme définit également. L'outil montre l'arrondi au plus proche, mode par défaut partout et seul mode exposé par la plupart des langages. Et il ne dit rien des charges utiles de NaN : un NaN transporte des bits qui peuvent varier d'une opération à l'autre, mais rien de portable n'en dépend, aussi l'outil se borne-t-il à signaler que la valeur n'est pas un nombre.
Si c'est l'écriture binaire exacte du décimal que vous avez saisi qui vous intéresse, et non celle de la valeur stockée, c'est une autre question, à laquelle répond notre convertisseur de bases : il vous montrera un dixième comme une fraction binaire infiniment périodique. L'écart entre cette écriture infinie et l'écriture finie présentée ici est précisément l'erreur de représentation.
Pourquoi est-ce gratuit ?
Ce n'est que de l'arithmétique entière, exécutée dans votre navigateur. Il n'y a rien à faire tourner sur un serveur, donc rien à facturer et aucun compte à créer.
Rien de ce que vous saisissez n'est envoyé, conservé ni journalisé. L'entrée est un nombre, et elle ne quitte jamais l'onglet.