L'idée de base
Un ordinateur n'a pas une infinité de chiffres pour écrire un nombre. Il travaille en binaire avec une boîte de taille fixe (souvent 64 bits, le float dit à double précision). Dès qu'un nombre ne rentre pas exactement dans cette boîte, la machine l'arrondit au plus proche qu'elle sait représenter. Cette petite erreur, invisible au début, peut s'accumuler.
Ce n'est pas un défaut de Python ou de JavaScript : c'est la norme IEEE 754, identique dans presque tous les langages.
Le grand classique qui choque tout le monde
print(0.1 + 0.2) # 0.30000000000000004 print(0.1 + 0.2 == 0.3) # FalsePourquoi ? Parce que 0.1 en binaire, c'est comme 1/3 en décimal : 0,3333... à l'infini. La machine coupe. Trois petites coupures additionnées, et le résultat tombe à côté.
Démo : le calculateur à double affichage
Tape deux nombres décimaux et compare ce que voit l'humain (calcul exact) avec ce que voit la machine (calcul en float).
Addition
Démo : l'accumulation qui dérape
On additionne 0.1 un grand nombre de fois. Chaque petite erreur va dans le même sens et finit par se voir. C'est ce genre de phénomène qui a fait rater sa cible au missile Patriot en 1991.
Somme répétée
Les deux grandes familles d'erreurs
| Type | Ce qui se passe | Exemple parlant |
|---|---|---|
| Arrondi de représentation | Le nombre n'existe pas exactement en binaire | 0.1 n'est pas vraiment 0,1 |
| Erreur d'annulation | On soustrait deux nombres très proches, les décimales utiles disparaissent | 1.0000001 - 1.0000000 |
Comment s'en protéger (réflexes de pro)
1. Ne jamais tester l'égalité de deux flottants. On compare à une tolérance :
if abs(a - b) < 1e-9: # assez proche ...2. Pour l'argent : pas de float. On utilise decimal.Decimal ou on travaille en cents (entiers).
3. Sommer du plus petit au plus grand, ou utiliser math.fsum() qui compense les erreurs :
Complément jumeau : les débordements de variables, quand c'est la taille de la boîte qui trahit.