90 votes

Convertir un flottant en chaîne de caractères sans l'arrondir

Je suis en train de faire un programme qui, pour des raisons qui n'ont pas besoin d'être expliquées, nécessite qu'un float 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 une solution ? Voici le code utilisé si vous voulez savoir :

len(str(float(x)/3))

2 votes

Si x est à l'origine str, pourquoi la distribution ?

1 votes

-1 : Pas d'exemples la sortie requise pour différentes valeurs de x . En l'absence d'exemples, nous ne pouvons que deviner le problème.

0 votes

130voto

John Fouhy Points 14700

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 "d'arrondi" vous posent. 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 .

12voto

nosklo Points 75862
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 du tutoriel python.

Une solution serait d'utiliser un type qui suit spécifiquement les nombres décimaux, comme le type de python decimal.Decimal :

>>> print len(str(decimal.Decimal('0.1')))
3

0 votes

Bon article sur la façon de travailler avec les résultats flottants de la division : stackoverflow.com/questions/2958684/python-division

4voto

Francesco Points 2139

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 que cela peut aider ? decimal est dans python stdlib depuis 2.4, avec des ajouts dans python 2.6.

J'espère que cela vous aidera, Francesco

0voto

Harsh Wardhan Points 1346

Je sais que c'est trop tard mais pour ceux qui viennent ici pour la première fois, j'aimerais poster une solution. J'ai une valeur flottante index et une chaîne imgfile et j'ai eu le même problème que vous. Voici comment j'ai résolu le problème

index = 1.0
imgfile = 'data/2.jpg'
out = '%.1f,%s' % (index,imgfile)
print out

Le résultat est

1.0,data/2.jpg

Vous pouvez modifier cet exemple de mise en forme à votre convenance.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X