Tous les articles

IEEE 754 : pourquoi 0.1 + 0.2 n'est pas égal à 0.3 dans le code

Ouvrez un interpréteur Python et tapez 0.1 + 0.2 — au lieu de 0.3, vous obtenez 0.30000000000000004. Ce n'est pas un bug propre à Python : c'est une conséquence directe de la façon dont la norme IEEE 754 représente les nombres fractionnaires en binaire, et le même résultat apparaît en JavaScript, en Java, en C#, et dans presque tout autre langage bâti sur cette norme.

Les trois parties d'un nombre à virgule flottante

Un nombre IEEE 754 est stocké sous forme de trois composants : un signe (positif ou négatif), une mantisse (les chiffres significatifs du nombre) et un exposant (la puissance de déplacement de la virgule). C'est similaire à la notation scientifique : 1.5 × 10², mais en binaire.

Pourquoi 0.1 ne peut pas être représenté exactement en binaire

0.1 en décimal est une fraction infinie en binaire (de façon similaire à 1/3 qui est infini en décimal). Un ordinateur ne stocke qu'un nombre limité de bits de mantisse, donc le nombre est arrondi à la valeur représentable la plus proche — et c'est cet arrondi qui produit l'« erreur » visible.

Là où ça pose vraiment problème : mesures scientifiques cumulées

Dans un calcul scientifique qui additionne des milliers de mesures en virgule flottante, chaque arrondi individuel est infime, mais les erreurs peuvent s'accumuler au lieu de s'annuler, faussant sensiblement un résultat agrégé sur un grand jeu de données. C'est pourquoi les bibliothèques de calcul scientifique privilégient des algorithmes de sommation compensée plutôt qu'une simple addition flottante répétée.

Pourquoi c'est utile

  • Comprendre et diagnostiquer des erreurs d'arrondi inattendues dans des calculs financiers ou scientifiques.
  • Voir la représentation binaire exacte d'un nombre à virgule flottante donné.
  • Expliquer à un collègue ou un étudiant pourquoi comparer des nombres fractionnaires par égalité exacte est une mauvaise pratique.

Les nombres subnormaux près de zéro

Lorsqu'un nombre est trop petit pour la représentation habituelle (un significande commençant par un 1 implicite), IEEE 754 passe en mode subnormal (dénormalisé), où ce 1 implicite est abandonné — cela permet de représenter des nombres encore plus proches de zéro, au prix d'une perte progressive de précision plutôt que d'un saut brutal vers zéro. Cette transition « en douceur » vers zéro est préférable à une annulation brutale, mais les calculs subnormaux sont sensiblement plus lents que les calculs normaux sur certains processeurs.

Essayer l'outil