Forum de mathématiques - Bibm@th.net
Vous n'êtes pas identifié(e).
- Contributions : Récentes | Sans réponse
#1 05-10-2011 13:58:35
- karlun
- Membre
- Inscription : 05-05-2010
- Messages : 216
(Python): Je suis bloqué . Petite question:
Bonjour,
M'étant remis (doucement) à la programmation (transposition en Python de l’algorithme "calcul à la main des racines carrées") je suis obligé d'user de subterfuges pour éviter de recevoir le genre de réponse comme ci-dessous.
>>>5.7-3.9
1.8000000000000003
>>>
Pfff! c'est quoi qui faut faire pour que 5.7-3.9 = 1.8 (tout sec)
Merci beaucoup.
Qui trouve, cherche.
Hors ligne
#2 05-10-2011 14:25:26
- yoshi
- Modo Ferox
- Inscription : 20-11-2005
- Messages : 16 947
Re : (Python): Je suis bloqué . Petite question:
Salut karlun,
Je te rassure tout de suite : ce n'est pas la faute de Python...
Ceci est dû à la représentation des nombres décimaux par les bécanes : tu n'en peux mais...
Le subterfuge définitif (en fait il y en a deux : le premier est vraiment un subterfuge) :
1. Essaie donc :
>>> print 5.7-3.9
1.8
2. Réalisable avec un maximum de 30 à 100 décimales (estimation personnelle), selon la complexité des calculs, sinon les délais sont prohibitifs : le module nommé decimal...
Va voir là : http://docs.python.org/library/decimal.html.
N-B : si tu ajoutes print devant les exemples du site, dans les réponses affichées ne figureront pas le mot Decimal, ni les ' encadrant les nombres et les parenthèses.
@+
PS
J'ai été confronté à ce problème : la seule solution que j'ai trouvée est de travailler avec des entiers (prendre les parties décimales comme des entiers) et placer la virgule (point décimal) correctement après via conversion en chaînes de caractères
Arx Tarpeia Capitoli proxima...
Hors ligne
#3 05-10-2011 15:44:31
- totomm
- Membre
- Inscription : 25-08-2011
- Messages : 1 093
Re : (Python): Je suis bloqué . Petite question:
Bonjour,
J'utilise couramment round(x[, n]) avec n=12 pour conserver le maximum de rapidité en flottant double (16 décimales)
exemple :
>>> round(5.7-3.9,12)
1.8
>>> round(5.7-3.9,15)
1.8
>>> round(1.9999999999999996,15)
2.0
Cordialement
Hors ligne
#4 05-10-2011 16:20:08
- yoshi
- Modo Ferox
- Inscription : 20-11-2005
- Messages : 16 947
Re : (Python): Je suis bloqué . Petite question:
Re,
Je sais, je suis déjà passé par là...
Tiens, quelques éléments d'appréciation :
>>> 1.0/(5**16)
6.5535999999999999e-12
>>> print 1.0/(5**16)
6.5536e-12
>>> round(1.0/(5**16),12)
7.0000000000000001e-12
>>> round(1.0/(5**16),16)
6.5535999999999999e-12
>>>
>>> from __future__import division
>>>
>>> round((1/5**12),16)
4.0959999999999999e-09
>>> round((1/5**12),13)
4.0959999999999999e-09
>>> round((1/5**12),14)
4.0959999999999999e-09
>>> round((1/5**12),12)
4.0959999999999999e-09
>>>
Bizarre..
Est-ce que Python v 3.2 donne aussi 7.0000000000000001e-12 et 6.5535999999999999e-12 ?
Les deux ne sont pas corrects...
Cela dit, avec la gestion en nombre entiers, j'ai pu calculer les... 20000 premières décimales du nombre d'or en une quinzaine de secondes.
Parce que je pense que karlun n'a pas l'intention de s'arrêter à une douzaine de décimales, ni même à 50 ou 100...
@+
PS
J'ai un élément de réponse à ma question :
Note
The behavior of round() for floats can be surprising: for example, round(2.675, 2) gives 2.67 instead of the expected 2.68. This is not a bug: it’s a result of the fact that most decimal fractions can’t be represented exactly as a float. See Floating Point Arithmetic: Issues and Limitations for more information.
Et donc retour à la case départ...
Donc la méthode round n'est pas fiable à 100 %.
C'est vrai, je me souviens maintenant : il y a longtemps, j'avais noté ça et pour contourner le problème j'avais réécrit une fonction arrondi (je vais rechercher le prog en question)...
Dernière modification par yoshi (05-10-2011 16:24:50)
Arx Tarpeia Capitoli proxima...
Hors ligne
#5 05-10-2011 19:00:04
- karlun
- Membre
- Inscription : 05-05-2010
- Messages : 216
Re : (Python): Je suis bloqué . Petite question:
Bonsoir et merci,
En effet je me suis déjà dirigé vers le maniement des entiers car malgré mon subterfuge je ne pouvais dépasser un certain nombre de « chiffres solution » car le programme me retournait le message suivant:
« OverflowError: integer division result too large for a float »
et ça ne m'arrangeait pas.
Comme le pressent bien Yoshi, je ne me contente pas de quelques dizaines (centaines) de décimales...
Mais ça me turlupinait quand-même; comment un calcul si simple peut indiquer un résultat «même infinitésimalement » faux.
Me voila rassurré.
A+-*/
Qui trouve, cherche.
Hors ligne