Pourquoi 0.1 + 0.2 != 0.3 ?


Une histoire de changement de base

Si vous avez déjà un peu programmé, quel que soit le langage que vous ayez utilisé vous avez sûrement dû vous heurter à ce problème. À titre d'exemple, l'opération 0.1 + 0.2 ne retourne pas exactement 0.3 comme attendu mais plutôt 0.30000000000000004.

Mais que se passe-t-il donc ?

Pour ce faire, il faut tout d'abord comprendre comment les nombres à virgule flottante sont représentés par votre ordinateur. La norme utilisée par quasiment tous les matériels est l'IEEE-754. Elle définit deux codages ; un sur 4 octets (32 bits) et un autre sur 8 octets (64 bits) mais l'implémentation reste globalement la même pour les deux. Les valeurs que je vais donner correspondent au codage sur 8 octets car étant le plus utilisé.

Vous connaissez très certainement la notation scientifique d'un nombre ; au lieu d'écrire c = 300 000 000 m/s on préfère utiliser c = 3*10^8 m/s ou c = 3E8 m/s. Cela permet d'écrire de grands nombres sans utiliser trop de caractères. Figurez-vous que c'est exactement la même chose pour l'ordinateur.

Sur les 64 bits de codage :

L'exposant représente la puissance de 10 et la mantisse un nombre entre 0 inclus et 10 exclu. Sauf qu'ils sont tous deux stockés en binaire ce qui pose un problème car nous comptons en base 10 ! Pour résoudre ce problème, votre ordinateur va procéder à un changement de base et c'est justement ce changement de base qui est la source de cette particularité.

Il se trouve que 0.1 est représenté comme valant légèrement plus, mais cette imprécision est corrigée par votre ordinateur en tronquant les décimales trop imprécises (lorsque supérieures à 16). De la même façon, 0.2 vaut lui aussi légèrement plus et encore une fois l'erreur est corrigée. Mais lorsqu'il s'agit de les additionner, les erreurs se cumulent et l'arrondi le plus proche est tranché : c'est 0.30000000000000004 qui est choisi à la place de 0.3.

Comment y remédier

Les moyens pour contourner ce problème sont variables suivant les langages. Mais certaines choses restent valables quelque soit la plateforme utilisée :


Références


© Florian Cassayre 2017
Version 3e7a85f