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.