Je suis en train de réaliser un programme qui, pour des raisons qu'il n'est pas nécessaire d'expliquer, exige qu'un flottant soit converti en une chaîne de caractères pour être compté avec len(). Cependant, avec str(float(x)), x est arrondi lorsqu'il est converti en chaîne de caractères, ce qui perturbe tout le processus. Quelqu'un connaît-il un moyen de résoudre ce problème ? Voici le code utilisé si vous voulez savoir :
len(str(float(x)/3))
Une certaine forme d'arrondi est souvent inévitable lorsqu'on traite des nombres à virgule flottante. En effet, les nombres que vous pouvez exprimer exactement en base 10 ne peuvent pas toujours être exprimés exactement en base 2 (que votre ordinateur utilise).
Par exemple :
>>> .1
0.10000000000000001
Dans ce cas, vous voyez .1 converti en une chaîne de caractères en utilisant repr
:
>>> repr(.1)
'0.10000000000000001'
Je crois que python supprime les derniers chiffres lorsque vous utilisez str() afin de contourner ce problème, mais c’est une solution partielle qui ne permet pas de comprendre ce qui se passe.
>>> str(.1)
'0.1'
Je ne sais pas exactement quels problèmes l'arrondi vous cause. Peut-être feriez-vous mieux d'utiliser le formatage des chaînes de caractères pour contrôler plus précisément vos résultats ?
Par exemple
>>> '%.5f' % .1
'0.10000'
>>> '%.5f' % .12345678
'0.12346'
[Documentation ici][1].
[1] : http://docs.python.org/library/string.html#formatstrings
len(repr(float(x)/3))
Cependant, je dois dire que ce n'est pas aussi fiable que vous le pensez.
Les flottants sont saisis/affichés comme des nombres décimaux, mais votre ordinateur (en fait, votre bibliothèque C standard) les stocke en binaire. Cette transition a des effets secondaires :
>>> print len(repr(0.1))
19
>>> print repr(0.1)
0.10000000000000001
L'explication de ce phénomène se trouve dans [ce chapitre][1] du tutoriel python.
Une solution serait d'utiliser un type qui gère spécifiquement les nombres décimaux, comme [decimal.Decimal
][2] de python :
>>> print len(str(decimal.Decimal('0.1')))
3
[1] : http://docs.python.org/tutorial/floatingpoint.html [2] : http://docs.python.org/library/decimal.html
D'autres réponses ont déjà souligné que la représentation des nombres flottants est un problème pour le moins épineux.
Comme vous ne donnez pas assez de contexte dans votre question, je ne peux pas savoir si le module décimal peut être utile pour vos besoins :
http://docs.python.org/library/decimal.html
Entre autres choses, vous pouvez spécifier explicitement la précision que vous souhaitez obtenir (voir la documentation) :
>>> getcontext().prec = 6
>>> Decimal('3.0')
Decimal('3.0')
>>> Decimal('3.1415926535')
Decimal('3.1415926535')
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85987')
>>> getcontext().rounding = ROUND_UP
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85988')
Un exemple simple à partir de mon prompt (python 2.6) :
>>> import decimal
>>> a = decimal.Decimal('10.000000001')
>>> a
Decimal('10.000000001')
>>> print a
10.000000001
>>> b = decimal.Decimal('10.00000000000000000000000000900000002')
>>> print b
10.00000000000000000000000000900000002
>>> print str(b)
10.00000000000000000000000000900000002
>>> len(str(b/decimal.Decimal('3.0')))
29
Peut-être cela peut-il vous aider ? decimal est dans python stdlib depuis 2.4, avec des ajouts dans python 2.6.
J'espère que cela vous aidera, Francesco