OVH Cloud OVH Cloud

Erreur de calcul sous Python

15 réponses
Avatar
Eric Grambier
Bonjour,

Débutant sous Python 2.4 je ne comprends pas pourquoi quand je lui
demande de calculer 54.3/3 il me donne comme résulat 18.0999...
Il ne s'agit même pas 'un arrondi puisque le résultat est simple et avec
une seule décimale.

Qui peut m'aider là dessus s'il vous plaît.

Merci

10 réponses

1 2
Avatar
Damien Wyart
* Eric Grambier in fr.comp.lang.python:
Débutant sous Python 2.4 je ne comprends pas pourquoi quand je lui
demande de calculer 54.3/3 il me donne comme résulat 18.0999...


<http://www.python.org/doc/2.4.1/tut/node16.html>
<http://python.org/doc/2.4/whatsnew/node9.html>

--
DW

Avatar
Eric Grambier
Bonjour,

N'étant pas fluent je ne suis pas sûr d'avoir tout coompris si ce n'est
qu'un irrationnel ne se limite pas à son expression avec quelques
décimales derrière la virgule.

MAIS comment se fait-il que Python ne sache pas faire sans erreur une
opération aussi simple que 54.3/3 qui fait 18.1 et c'est tout ;-)

Merci pour votre aide

Eric


* Eric Grambier in fr.comp.lang.python:

Débutant sous Python 2.4 je ne comprends pas pourquoi quand je lui
demande de calculer 54.3/3 il me donne comme résulat 18.0999...



<http://www.python.org/doc/2.4.1/tut/node16.html>
<http://python.org/doc/2.4/whatsnew/node9.html>




Avatar
Laurent Pointal
Eric Grambier wrote:
Bonjour,

N'étant pas fluent je ne suis pas sûr d'avoir tout coompris si ce n'est
qu'un irrationnel ne se limite pas à son expression avec quelques
décimales derrière la virgule.

MAIS comment se fait-il que Python ne sache pas faire sans erreur une
opération aussi simple que 54.3/3 qui fait 18.1 et c'est tout ;-)


C'est tout... en décimal.

En binaire... sur des nombres flottants, c'est une autre paire de manches.


Un petit article en patois:
http://www.jamescoulter.com/editorials/binary_fractions.htm

Une petite entrée dans Wikipedia:
http://fr.wikipedia.org/wiki/Virgule_flottante

Qui donne un lien sympa:
http://babbage.cs.qc.edu/courses/cs341/IEEE-754.html

Bonnes lectures.

Avatar
Paul Gaborit
À (at) Tue, 13 Sep 2005 15:59:57 +0200,
Eric Grambier écrivait (wrote):
MAIS comment se fait-il que Python ne sache pas faire sans erreur une
opération aussi simple que 54.3/3 qui fait 18.1 et c'est tout ;-)


Tout simplement par ce que 18.1 (comme 54.3 d'ailleurs) s'écrit avec
une infinité de décimales en base 2. Votre ordinateur, n'ayant pas une
mémoire infinie, ne stocke donc que quelques-unes de ces décimales. Et
python affiche cette valeur approximative reconvertie telle quelle en
base 10.

Vous vous demandez peut-être pourquoi votre calculette (ou d'autres
programmes/langages) ne fait pas cette même erreur... En fait, elle
fait pareil mais arrondit quelques décimales au-dessus de sa précision
interne pour cacher l'effet des erreurs d'arrondi (mais uniquement à
l'affichage). Python souffre en fait de son honnêté ;-)

Pour pallier cela, certains programmes de calcul proposent des nombres
rationnels en précision arbitraire ou font du calcul formel mais ils
souffrent alors d'autres limitations...

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>

Avatar
frederic LESUEUR
Eric Grambier wrote:

Bonjour,

N'étant pas fluent je ne suis pas sûr d'avoir tout coompris si ce n'est
qu'un irrationnel ne se limite pas à son expression avec quelques
décimales derrière la virgule.

MAIS comment se fait-il que Python ne sache pas faire sans erreur une
opération aussi simple que 54.3/3 qui fait 18.1 et c'est tout ;-)

Normalement si tu fais un print du résultat il devrait t'afficher la bonne

valeur. En faite il s'agit de la représentation en interne niveau
processeur des chiffres décimaux : le chiffre 18,1 n'existe pas il s'agit
en fait de 18,0999999. Mais pas de souci, python calcul quand même les
bonnes valeurs.

Avatar
Amand Tihon
Eric Grambier wrote:

MAIS comment se fait-il que Python ne sache pas faire sans erreur une
opération aussi simple que 54.3/3 qui fait 18.1 et c'est tout ;-)


Python sait le faire, avec le module "decimal".
Cependant, si on utilise simplement les floats, python laisse faire le
processeur, qui compte différemment.

En simplifiant:
Pour le CPU, les entiers sont notés comme une addition d'exposants de 2 (1,
2, 4, 8, 16, ...) : On pourra toujours tomber juste si on a assez de bi ts.
Les parties décimales sont notées comme une addition d'exposants né gatifs de
2 (1/2, 1/4, 1/8, 1/16, ...) et ce système ne permet pas, avec un nom bre
fini de bits, de coder tous les nombres décimaux de manière exacte. C'est
la raison de ton arrondi (qui en est bien un. Peut-être pas dans la b ase
1/10 qu'on utilise tous les jours, mais bien dans la base 1/2 utilisé e par
ton processeur)

En espérant avoir été clair,
--
Amand Tihon

Avatar
Eric Grambier
Bonjour,

Donc pour résumer :
Python m'affiche un arrondi puisqu'il fait le calcul en base 2 mais en
fait le calcul est juste quand même et si je le réutilise genre
(54.3/3)*10 il devrait me donner 181 (hein c'est ça ?;-)

Une seule solution pour qu'il me donne avec print la réponse exacte en
base 10 c'est d'utiliser le module décimal.

Ben merci pour toutes vos explications.

Bien cordialement à tous

Eric
Avatar
nico
Aller, j'en remets une couche ;)

Bonjour,

N'étant pas fluent je ne suis pas sûr d'avoir tout coompris si ce n'est
qu'un irrationnel ne se limite pas à son expression avec quelques
décimales derrière la virgule.
Dans un ordinateur, tout fonctionne en nombres binaires. Y compris les nombres représentés en décimal.

Tout est codé avec des nombres en puissance de 2.
Pour les nombres entiers, c'est facile :
54 = 32 + 16 + 4 + 2
Pour les nombres a virgule, c'est pareil sauf qu'il faut coder la partie décimale en plus :
Pour simplifier :
54.3 = 54 + 0.3
0.3 = 1/4 + 1/32 + 1/64 + 1/512 + ...
Aie, il faut un nombre infini de chiffres binaires pour coder 0.3. Tant pis, on va faire au plus près avec un nombre limité de chiffres.


MAIS comment se fait-il que Python ne sache pas faire sans erreur une
opération aussi simple que 54.3/3 qui fait 18.1 et c'est tout ;-)

Python comme les autres languages :(

Tu peux toujours utiliser le type Decimal. Y a plus de problèmes de précision mais bonjour les performances. On n'a rien sans rien.

Nicolas

Avatar
Amand Tihon
Eric Grambier wrote:

Une seule solution pour qu'il me donne avec print la réponse exacte en
base 10 c'est d'utiliser le module décimal.


Mieux, avec print, il corrige tout seul :

54.3/3
18.099999999999998



print 54.3/3
18.1




--
Amand Tihon



Avatar
nico
Bonjour,

Donc pour résumer :
Python m'affiche un arrondi puisqu'il fait le calcul en base 2 mais en
fait le calcul est juste quand même et si je le réutilise genre
(54.3/3)*10 il devrait me donner 181 (hein c'est ça ?;-)

Non, le calcul est faux en interne. Python affiche exactement ce qu'il calcule.

Essaye 54.3/3*10
Essaye 54.3*10/3
Et oui, l'ordre a une importance.

Une seule solution pour qu'il me donne avec print la réponse exacte en
base 10 c'est d'utiliser le module décimal.

Tu peux aussi faire de la virgule fixe avec des entiers si c'est adapté à ton application. Perso, c'est ce que je fais avec une application de gestion de comptes bancaires. 2 chiffres apprès la virgule me suffisent.

La virgule fixe consiste à tout multiplier par une valeur fixe. Dans mon cas : 100. Tous mes nombres sont traités en entiers (donc pas d'arrondis). Seul l'affichage est spécial puisqu'il faut remttre la virgule à sa place.

Ben merci pour toutes vos explications.

Bien cordialement à tous

Eric


1 2