Truc informatique

Le piège des nombres à virgule

Demande à Python combien font 0.1 + 0.2. Réponse : 0.30000000000000004. Non, ton ordinateur n'est pas cassé. C'est une bizarrerie normale des nombres à virgule, et savoir la gérer t'évitera des heures de doute.

Le petit choc

Clique pour voir ce que ton propre navigateur répond (il utilise exactement la même norme que Python) :

🧮 Calculs en direct

Le même résultat tomberait dans Python : ce n'est pas le langage, c'est la machine.

Pourquoi cette mini-erreur ?

L'ordinateur range les nombres à virgule en binaire (des 0 et des 1). Or certaines fractions toutes simples en décimal n'ont pas d'écriture exacte en binaire, un peu comme 1/3 = 0,3333... n'a pas de fin en décimal.

Du coup, 0.1 et 0.2 sont stockés presque exactement, et la minuscule erreur se voit quand on les additionne. C'est infime (de l'ordre de 0,0000000000000001), mais bien réel.

La règle d'or : ne jamais tester l'égalité exacte

Comme deux calculs peuvent finir à un cheveu l'un de l'autre, ne compare jamais deux flottants avec ==. Demande plutôt s'ils sont assez proches :

# Fragile : presque jamais Vrai comme on l'espère
0.1 + 0.2 == 0.3        # → False

# Solide : "sont-ils assez proches ?"
abs((0.1 + 0.2) - 0.3) < 1e-9   # → True

Le 1e-9 veut dire 0,000000001 : une tolérance minuscule. Si l'écart est plus petit que ça, on considère les deux nombres égaux. (numpy offre aussi np.isclose(a, b) qui fait exactement ce travail.)

Pour afficher proprement : arrondir

Quand c'est juste pour montrer un résultat, arrondis. Tu choisis le nombre de décimales :

resultat = 0.1 + 0.2

round(resultat, 2)        # → 0.3   (arrondi à 2 décimales)
f"{resultat:.2f}"         # → "0.30" (texte formaté, 2 décimales)

💡 Attention de ne pas confondre

Arrondir pour afficher (jolis résultats à l'écran) et comparer avec une tolérance (tester une égalité) sont deux gestes différents. Pour de l'argent ou de la comptabilité exacte, on évite carrément les flottants : on compte en cents (des entiers) ou on utilise le module decimal.