Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 12/11/2007, à 18:03

SiscoL

Sous Python 1.9 donne 1.89999... ?

Bonjour à tous,

je vous préviens je ne suis pas développeur et je n'y connais pas grand chose en programmation. Mais malgré tout, je suis curieux et à travers un livre je découvre en ce moment le langage Python, ça m'intéresse.

Je suis sous Ubuntu 7.10 (depuis peu d'ailleurs je suis sous linux et très content de l'être) et lorsque je tape en ligne de commande ceci, j'ai des réponses inexactes.

>>> 1.9
1.8999999999999999
>>> 2*2.1
4.2000000000000002

Quelqu'un peut-il m'expliquer pourquoi Python fait-il de telles approximations ? Quelqu'un peut-il me fournir une explication que je puisse comprendre ?
Attention, ce phénomène ne me gêne nullement, c'est juste par curiosité que je pose la question. Est-ce pareil chez vous ?

Merci d'avance.

PS : quand j'étais sous windows, j'avais le même phénomène.


François

Hors ligne

#2 Le 12/11/2007, à 18:29

denis_aec

Re : Sous Python 1.9 donne 1.89999... ?

Ah, les nombres flottants :
http://fr.wikipedia.org/wiki/Nombre_flottant

De l'arrondi sur les nombres flottants ...

Hors ligne

#3 Le 12/11/2007, à 18:30

slapierre

Re : Sous Python 1.9 donne 1.89999... ?

Les développements décimaux 1.9 et 1.8999999999999999 représentent le même nombre :

Labelle et Mercier - ISBN 2-89113-448-6 a écrit :

Un nombre réel x admet deux développements décimaux distincts seulement s'il en admet un se terminant par une suite infinie de chiffres 9 et un autre fini.

Toutefois, saisir le nombre 2.1 retourne 2.000...001, ce qui est bien embêtant!
Pour augmenter la précision, j'ai trouvé les infos suivantes dans le tutoriel de python : http://docs.python.org/tut/node13.html#SECTION0013800000000000000000

Simon


"Le spectre de la folie nous empêchera-t-il de hisser l'étendard de l'imagination?" - André Breton

Hors ligne

#4 Le 12/11/2007, à 22:58

SiscoL

Re : Sous Python 1.9 donne 1.89999... ?

Merci pour vos réponses et vos liens.

1) Mais j'avoue ne pas avoir trouvé une réponse précise à  ma question. J'ai vraiment du mal à  comprendre pourquoi Python n'arrive pas à  calculer aussi bien qu'une pauvre calculatrice à  trois francs six sous achetée au supermarché du coin.

2) Au fait, ce même phénomène se produit-t-il pour tous les langages ?

François


François

Hors ligne

#5 Le 13/11/2007, à 04:13

slapierre

Re : Sous Python 1.9 donne 1.89999... ?

http://www.linuxtopia.org/online_books/programming_books/introduction_to_python/python_tut_87.html

Simon


"Le spectre de la folie nous empêchera-t-il de hisser l'étendard de l'imagination?" - André Breton

Hors ligne

#6 Le 13/11/2007, à 10:42

aleph

Re : Sous Python 1.9 donne 1.89999... ?

> SisCoL
> ...je vous préviens je ne suis pas développeur et je n'y connais pas grand chose en programmation....

Quelques réponses sous forme de "recettes".

- Un nombre à  virgule, appelé nombre flottant dans le jargon informatique, ne peut être représenté dans la "machine" de façon exacte.
- Python comme tous les langages ou Excel, Calc travaille avec ces nombres. Python est d'ailleurs écrit en C.
- Dans un "mode console" Python permet d'afficher une représentation de ces nombres au plus près de leurs réalités dans la machine. Surprenant mais parfaitement correct. A noter la différence entre un >>> a et un >>> print a si "a = 1.9".
- Tout ceci est correct et dans la pratique, c'est à  dire dans les calculs ou la programmation,  il n'y a aucun souci à  se faire.
- Il est illusoire de croire qu'un module comme decimal sera d'une utilité quelconque pour l'usage habituel. Ce n'est pas son utilité première.
- En résumé et pour être court, ceci n'est qu'un problème d'affichage ou pour être précis, de représentation des nombres à  l'écran (v. psi)

- Très bonne chose (la meilleure) que d'apprendre Python par le biais d'une console.

- L'interpréteur interactif psi,  http://spinecho.ze.cx/ > psi, illustre ceci. Il dispose d'un mécanisme qui affiche les nombres de "façon plus humaine" ou "plus attendue". En complément, les caractères européens sont aussi affichés de façon "plus naturelle".

img1mg4.png

#7 Le 13/11/2007, à 15:26

Le Farfadet Spatial

Re : Sous Python 1.9 donne 1.89999... ?

Salut à  tous !

   Déjà  pas mal de réponses intéressantes. J'ajoute mon grain de sel.

SiscoL a écrit :

1) Mais j'avoue ne pas avoir trouvé une réponse précise à  ma question. J'ai vraiment du mal à  comprendre pourquoi Python n'arrive pas à  calculer aussi bien qu'une pauvre calculatrice à  trois francs six sous achetée au supermarché du coin.

Il ne faut pas croire : la calculatrice à  trois francs six sous fait des erreurs de calculs. La TI 92+ également, d'ailleurs.

   Plus encore, le super calculateur Earth Simulator du CEA fait des erreurs de calculs. On y coupe pas !

   Par contre, il y a une différence entre calculatrice et ordinateur : la plupart des ordinateurs respectent la norme IEE 754, c'est-à -dire que les nombres à  virgules flottantes sont codés en base 2, lorsque les calculatrices utilisent souvent la base 10.

2) Au fait, ce même phénomène se produit-t-il pour tous les langages ?

Sur ton problème, il y a une part de réactions particulières de Python. Cela dit, quelque soit le langage choisit, l'ordinateur fera des erreurs de calcul.

   Sur mon site sur mes thèmes de recherche (http://www.legos.obs-mip.fr/~lebars/), j'ai prévu de faire une page de vulgarisation au sujet des erreurs de calculs sur ordinateur. Malheureusement, je n'ai pas encore fini, il faudra peut-être attendre encore un mois ou deux avant que je le mette en ligne. En attendant, si tu cherches quelque chose d'un peu plus complet que ce que l'on t'a déjà  donné sur ce sujet et que tu n'as pas peur des choses un peu techniques, tu peux lire le premier chapitre de mon mémoire de Master 2, disponible dans la partie publications de mon site (http://www.legos.obs-mip.fr/~lebars/publications). Le mémoire s'appelle « Implémentation de la méthode CESTAC dans la bibliothèque BLAS. »

   à€ bientà´t.

                                                                                                                     Le Farfadet Spatial

Hors ligne

#8 Le 13/11/2007, à 23:38

SiscoL

Re : Sous Python 1.9 donne 1.89999... ?

Merci beaucoup pour toutes vos réponses.

En gros, sur la calculatrice, il y a aussi des erreurs mais on ne les voit en général pas car elle affiche seulement une valeur approchée qui va donner le résultat attendu, elle fait une sorte de print.

Un peu comme quand on fait ça avec python :

>>> a = 2.1
>>> b = 2
>>> a*b # ne donne pas le résultat attendu
4.2000000000000002
>>> print a*b # donne le résultat attendu
4.2

C'est à  peu près ça ? Non ?

Merci encore pour les liens.


François


François

Hors ligne

#9 Le 14/11/2007, à 00:25

Le Farfadet Spatial

Re : Sous Python 1.9 donne 1.89999... ?

Salut à  tous !

SiscoL a écrit :

C'est à  peu près ça ? Non ?

à€ peu près. Toutefois, si le mécanisme des erreurs est le même entre calculatrice et ordinateur --- passage d'un espace continu (les réels) à  un espace discret, --- les erreurs ne seront généralement pas les mêmes, parce que les calculatrices n'utilisent généralement pas le même espace que les ordinateurs --- pour les premières, les nombres à  virgules flottantes en base dix, les autres les nombres à  virgules flottantes en base deux. Pas la même erreur, mais l'erreur est aussi importante dans un cas comme dans l'autre.

   à€ bientà´t.

                                                                                                                                                Le Farfadet Spatial

Hors ligne

#10 Le 14/11/2007, à 09:07

aleph

Re : Sous Python 1.9 donne 1.89999... ?

Pour revenir à Python puisque c'est le sujet...

> SiscoL
> C'est à peu près ça ? Non ?

Grosso modo oui. Les mécanismes internes de Python pour voir, scruter, représenter le contenu d'un objet (rien à voir avec la POO) sont divers.
Si tu définis une variable a = 2.1 et l'affiche dans une console interactive, Python utilisera une méthode nommée __repr__. Tu trouveras la preuve de son existence en faisant par ex.

>>> a = 2.1
>>> dir(a)
['__abs__', '__add__', '__class__', '__coerce__', '__delattr__', '__div__',
'__divmod__', '__doc__', '__eq__', '__float__', '__floordiv__', '__ge__',
'__getattribute__', '__getformat__', '__getnewargs__', '__gt__', '__hash__',
'__init__', '__int__', '__le__', '__long__', '__lt__', '__mod__', '__mul__',
'__ne__', '__neg__', '__new__', '__nonzero__', '__pos__', '__pow__', '__radd__',
'__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__',
'__rfloordiv__', '__rmod__', '__rmul__', '__rpow__', '__rsub__', '__rtruediv__',
'__setattr__', '__setformat__', '__str__', '__sub__', '__truediv__']

Un "statement" print est un autre mécanisme.
Evidemment, voir le contenu d'une variable comme a dans le cas présent n'est possible que par l'utilisation d'un interpréteur *interactif*.

La conversion de a en une chaîne de caractères fonctionne un peu comme un print. Ici aussi, et c'est le but de ma remarque, Python et sa console permettent de différencier les représentation et l'affichage d'un str. Noter les apostrophes dans '2.1' .

>>> a
2.1000000000000001
>>> str(a)
'2.1'
>>> print str(a)
2.1

avec à nouveau l'utilisation de __repr__, mais cette fois associée au type str.

>>> dir(str(a))
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__',
'__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__',
'__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__',
'__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__rmod__', '__rmul__', '__setattr__', '__str__', 'capitalize', 'center', 'count', 
'decode', 'encode', 'endswith', 'expandtabs', 'find', 'index', 'isalnum',
'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 
'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust',
'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip',
'swapcase', 'title', 'translate', 'upper', 'zfill']

(Il est d'usage et recommendé d'écrire Python avec un P majuscule).