Visualiseur de motifs binaires en virgule flottante IEEE 754
Décompose un nombre décimal en son motif binaire IEEE 754 en simple précision (32 bits) ou double précision (64 bits), ou décode un motif binaire pour le reconvertir en valeur décimale. Le signe, l'exposant et la mantisse sont affichés avec un code couleur, avec prise en charge de NaN, de l'infini et des nombres dénormalisés.
L'exemple classique : pourquoi 0.1 + 0.2 ne donne pas 0.3
En JavaScript, `0.1 + 0.2` donne `0.30000000000000004`, et non `0.3`. L'examen des motifs binaires en double précision explique pourquoi.
| Valeur | Hexadécimal en double précision (64 bits) | Binaire en double précision (64 bits) |
|---|---|---|
| 0.1 | 0x3FB999999999999A | 0011111110111001100110011001100110011001100110011001100110011010 |
| 0.2 | 0x3FC999999999999A | 0011111111001001100110011001100110011001100110011001100110011010 |
| 0.3 | 0x3FD3333333333333 | 0011111111010011001100110011001100110011001100110011001100110011 |
| 0.1 + 0.2 | 0x3FD3333333333334 | 0011111111010011001100110011001100110011001100110011001100110100 |
0.1, 0.2 et 0.3 sont tous des fractions périodiques infinies en binaire, si bien qu'aucun d'eux ne tient exactement dans la mantisse de 52 bits et que chacun est arrondi. Comme les erreurs d'arrondi de 0.1 et de 0.2 ne s'annulent pas par hasard, leur somme finit par différer d'un seul bit du motif exact de 0.3 (0x3FD3333333333334). Essayez de saisir ces valeurs dans le convertisseur ci-dessus et comparez vous-même les derniers bits.
Astuces
- Convertissez 0.1, 0.2 et 0.3 en bits en double précision et comparez-les au résultat de 0.1+0.2 (0.30000000000000004) — vous pouvez repérer visuellement que seul le dernier bit diffère.
- Saisir « -0 » dans le champ décimal produit un motif binaire où seul le bit de signe est activé (différent de « +0 »). Comme nombres, 0 === -0, mais les représentations binaires sont distinctes.
- Lorsque le champ de l'exposant est entièrement nul, une mantisse nulle signifie zéro, et une mantisse non nulle signifie un nombre dénormalisé — une représentation spéciale utilisée pour atteindre des valeurs extrêmement proches de zéro au prix de la précision.
- Basculer entre simple précision (32 bits) et double précision (64 bits) pour une même valeur comme 0.1 montre à quel point l'erreur d'arrondi est plus importante en simple précision.
- Pour décoder un motif binaire et le reconvertir en valeur décimale, saisissez soit une chaîne hexadécimale précédée de `0x`, soit une chaîne binaire comportant exactement autant de chiffres que la précision sélectionnée (le préfixe `0b` est facultatif).
Questions fréquentes
Anecdote — Comment IEEE 754 est devenu un langage commun
Avant 1985, chaque fabricant d'ordinateurs utilisait sa propre représentation en virgule flottante. IBM, DEC, Cray et d'autres pouvaient calculer la même valeur, disons « 0.1 », et obtenir un comportement d'arrondi et des plages représentables subtilement différents, si bien que porter un programme numérique d'une machine à une autre produisait souvent des résultats légèrement différents. Pour résoudre ce chaos, un groupe de travail dirigé par William Kahan, de l'université de Californie à Berkeley — qui avait également participé à la conception du coprocesseur numérique Intel 8087 —, a mené la création d'une norme à l'échelle de toute l'industrie, publiée en 1985 sous le nom d'IEEE 754.
L'idée centrale d'IEEE 754 consiste à répartir un nombre fini de bits (32 ou 64) en trois rôles — signe, exposant et mantisse — afin d'approximer l'ensemble infini des nombres réels. L'exposant gère l'échelle (la grandeur du nombre), tandis que la mantisse gère la précision (le nombre de chiffres significatifs), ce qui permet à un nombre fixe de bits de couvrir avec souplesse aussi bien des grandeurs très petites que très grandes. L'exposant est stocké avec un biais ajouté (127 en simple précision, 1023 en double précision) afin que la simple comparaison de deux motifs binaires en tant qu'entiers non signés suffise à déterminer quelle valeur est la plus grande, évitant ainsi la complexité supplémentaire d'une représentation signée comme le complément à deux.
Seules les fractions dont le dénominateur est une puissance de deux (1/2, 1/4, 3/8, etc.) peuvent être représentées exactement en binaire. La valeur décimale 0.1 est la fraction 1/10, et comme 10 n'est pas une puissance de deux, elle devient la fraction binaire périodique infinie 0.0001100110011... Avec seulement un nombre fini de bits de mantisse disponibles, il faut la tronquer et l'arrondir à un moment donné — c'est la raison fondamentale pour laquelle un ordinateur ne peut pas représenter 0.1 exactement. C'est aussi pourquoi les systèmes comptables ayant besoin d'une arithmétique décimale exacte évitent généralement les nombres à virgule flottante au profit de l'arithmétique entière ou d'un type décimal dédié (comme le BCD).
IEEE 754 a ensuite été révisé en 2008 et en 2019, ajoutant la demi-précision (16 bits), la précision quadruple (128 bits) et des formats en virgule flottante décimale, mais la division fondamentale en signe, exposant et mantisse, ainsi que ses modes d'arrondi, sont restés inchangés depuis l'édition originale de 1985. Comme presque tous les types float/double de tous les langages de programmation se conforment à cette norme, la question « pourquoi 0.1 + 0.2 n'est pas égal à 0.3 ? » se pose essentiellement sous la même forme, quel que soit le langage utilisé.