0

Visualiseur flottant IEEE-754

Découvrez exactement comment un nombre décimal est stocké sous forme de nombre flottant IEEE-754 (bit de signe, bits d'exposant et bits de mantisse) et pourquoi des nombres comme 0,1 ne sont pas stockés exactement.

Buy Me a Coffee at ko-fi.com
Traitement... 0%
Normalisation
Calcul du biais d'exposant
Bits de mantisse en expansion
Terminé

Résultat

Chaque nombre à virgule flottante stocké par un ordinateur (un nombre JavaScript, un flottant C, un flottant Python) est codé de la même manière selon IEEE 754 : un bit de signe, un bloc de bits d'exposant et un bloc de bits de mantisse (fraction). La simple précision (32 bits) utilise 1 bit de signe, 8 bits d'exposant et 23 bits de mantisse ; la double précision (64 bits), le format derrière le type de nombre par défaut de presque toutes les langues, utilise 1 bit de signe, 11 bits d'exposant et 52 bits de mantisse. Cet outil prend n'importe quel nombre décimal que vous tapez, l'encode dans n'importe quelle largeur à l'aide du propre encodeur flottant DataView/ArrayBuffer du navigateur - la même machine sur laquelle votre code s'exécute réellement - et colore chaque bit en fonction de la région à laquelle il appartient.

L'encodage lui-même suit trois étapes, et cet outil les parcourt toutes au lieu de simplement afficher les derniers bits. Premièrement, la normalisation : le nombre est réécrit sous la forme 1.mantissa × 2^exposant, avec exactement un chiffre différent de zéro avant le point binaire (les nombres trop petits pour cela reçoivent à la place le traitement sous-normal, sans 1 implicite en tête). Deuxièmement, le biais d'exposant : puisque le champ d'exposant doit stocker les exposants positifs et négatifs sous forme de nombre non signé, un biais fixe (127 pour simple précision, 1023 pour double) est ajouté avant que le champ ne soit écrit en binaire. Troisièmement, la mantisse fractionnaire est étendue petit à petit avec la méthode classique « multiplier par deux, prendre la partie entière comme bit suivant, conserver le reste » - répétée jusqu'à ce que le champ de mantisse soit plein, auquel cas les bits restants décident si le résultat est arrondi à la hausse ou à la baisse (arrondi de moitié à pair, valeur par défaut de l'IEEE-754).

C'est exactement pourquoi un nombre aussi ordinaire que 0,1 n'est pas stocké exactement. En binaire, 0,1 est une fraction répétitive (0,0001100110011…, pour toujours), donc aucune mantisse finie ne peut la contenir avec précision – elle doit être arrondie quelque part. Encodez 0,1 sous forme de flottant 32 bits et relisez les bits, et vous n'obtenez pas 0,1 en retour : vous obtenez exactement 0,100000001490116119384765625. La double précision a 29 bits de mantisse supplémentaires avec lesquels travailler, donc son erreur d'arrondi est beaucoup plus petite, mais elle n'est pas nulle non plus - 0,1 car un double de 64 bits est exactement 0,1000000000000000055511151231257827021181583404541015625. Cet outil calcule cette valeur exacte stockée avec l'arithmétique des grands entiers (pas de raccourcis à virgule flottante) afin que l'écart entre ce que vous avez tapé et ce que le matériel conserve réellement ne soit jamais caché ou approximé.

Les valeurs spéciales obtiennent des modèles de bits exacts et réservés plutôt qu'un codage normal : zéro et zéro négatif ont des bits d'exposant et de mantisse entièrement nuls (seul le bit de signe diffère), ±Infinity a des bits d'exposant entièrement à un avec une mantisse entièrement nulle, et NaN a des bits d'exposant entièrement à un avec au moins un bit de mantisse défini. Tout ici s'exécute localement dans votre navigateur — rien de ce que vous tapez n'est téléchargé nulle part — ce qui en fait un endroit sûr pour créer une véritable intuition pour les bogues en virgule flottante : pourquoi `0.1 + 0.2 !== 0.3` dans presque tous les langages de programmation, pourquoi les textures float32 dans le code graphique perdent en précision alors que float64 ne le ferait pas, et pourquoi le code financier devrait généralement éviter complètement la virgule flottante binaire.