Des calculs déroutants☘
Au problème du nombre fini de chiffres s'ajoute le problème de la représentation des nombres décimaux en base 2. Cela donne des résultats dont il faut apprendre à se méfier...
Exemple
- 
Tout d'abord, calculons 0.1 + 0.1:En demandant à Python, si, pour lui,>>> 0.1 + 0.1 0.2 >>> 0.1 + 0.1 == 0.2 True0.1 + 0.1est bien égal à0.2, tout semble bien se passer.
- 
A présent, calculons 0.1 + 0.1 + 0.1:Étonnant, il semble que le résultat ne soit pas>>> 0.1 + 0.1 + 0.1 0.300000000000000040.3!
- 
Demandons alors à Python si 0.1 + 0.1 + 0.1est bien égal à0.3:Étonnant n'est-ce pas ?>>> 0.1 + 0.1 + 0.1 == 0.3 False
- 
De même : Python répond FAUX !>>> 0.1 + 0.2 == 0.3 False
Important
Cela n'est pas lié au langage Python. On retrouvera ce problème dans
tous les langages de programmation.
Ce problème est dû à la façon dont les nombres à virgule sont codés en
machine.
A retenir
On ne doit jamais tester l'égalité de deux flottants avec le comparateur
« == ».
Il faudra se rappeler de l'exemple du calcul de  0.1 + 0.1 + 0.1 ci-dessus.
Si l'on cherche à tester l'égalité de flottants en machine, on ne teste que
leur proximité (avec risques d'erreur donc).
Le module math de Python propose une fonction spécifique pour ce type de
test : isclose().
>>> from math import isclose
>>> isclose(0.1 + 0.2, 0.3)
True
Exemple☘
La fonction fractions_egales() a pour paramètres les entiers a, b, c
et d. Cette fonction renvoie True si la fraction \frac{a}{b} est égale
à la fraction \frac{c}{d} et False sinon.
- 
Quelle précondition sur les paramètres semble-t-il raisonnable d'imposer ? Une réponseLes paramètres betd, qui représentent les dénominateurs, doivent être non nuls.
- 
Complétez le code de la fonction en ajoutant une assertion pour traduire la précondition précédente. 1 2 3 4 5 6 def fractions_egales(a, b, c, d): """ a, b, c, d – int, entiers avec b et d non nuls Sortie: bool – True lorsque la fraction a/b est égale à c/d, False sinon """AttentionLe test if a/b == c/dserait une bien mauvaise idée.
 Rappelez-vous : on ne peut pas vérifier l'égalité de deux flottants avec «==» !Une solution1 2 3 4 5 6 7 8 def fractions_egales(a, b, c, d): """ a, b, c, d – int, entiers avec b et d non nuls Sortie: bool – True lorsque est égale à , False sinon """ assert (b!= 0) and (d!= 0), "dénominateur nul !" return a*d == b*c
Des règles de calcul étonnantes☘
Info
Soient a, b et c des nombres réels. On a : (a+b)+c = a+(b+c).
C'est ce que l'on appelle associativité de l'addition de nombres réels (le mot « associativité » est utilisé pour rappeler que l'on peut, pour additionner, « associer » les deux premiers ou « associer » les deux derniers).
En machine, l'addition des flottants n'est pas associative :
>>> (0.3 + 0.9) + 0.2
1.4
>>> 0.3 + (0.9 + 0.2)
1.4000000000000001
>>> (0.3 + 0.9) + 0.2 == 0.3 + (0.9 + 0.2)
False
L'essentiel des calculs en machine sur les flottants ne sont donc que des calculs de valeurs approchées.
On insiste donc, une fois de plus, sur la non-utilisation de « == » entre
flottants : l'information obtenue avec un test a == b (où a et b sont
de type float) ne concerne que les flottants et donne rarement une
information sur les nombres mathématiques qu'ils sont censés représenter.