web-dev-qa-db-fra.com

Conversion d'un float en chaîne sans l'arrondir

Je crée un programme qui, pour des raisons qui n'exigent pas d'explication, nécessite qu'un flottant soit converti en une chaîne à compter avec len (). Cependant, str (float (x)) a pour résultat que x est arrondi lorsqu’il est converti en une chaîne, ce qui jette tout l’élément. Est-ce que quelqu'un connaît un correctif pour cela? Voici le code utilisé si vous voulez savoir:

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

Une certaine forme d'arrondissement est souvent inévitable lorsqu'il s'agit de nombres à virgule flottante. En effet, les nombres que vous pouvez exprimer avec exactitude en base 10 ne peuvent pas toujours être exprimés avec exactitude en base 2 (utilisée par votre ordinateur).

Par exemple:

>>> .1
0.10000000000000001

Dans ce cas, vous voyez .1 être converti en chaîne à l'aide de repr:

>>> repr(.1)
'0.10000000000000001'

Je crois que python coupe les derniers chiffres lorsque vous utilisez str () afin de contourner ce problème, mais c'est une solution de contournement partielle qui ne remplace pas la compréhension de ce qui se passe.

>>> str(.1)
'0.1'

Je ne sais pas exactement quels problèmes vous causent "l'arrondissement". Vous feriez peut-être mieux d'utiliser le formatage de chaîne pour mieux contrôler votre sortie?

par exemple.

>>> '%.5f' % .1
'0.10000'
>>> '%.5f' % .12345678
'0.12346'

Documentation ici .

120
John Fouhy
_len(repr(float(x)/3))
_

Cependant, je dois dire que ce n'est pas aussi fiable que vous le pensez.

Les flottants sont entrés/affichés sous forme de nombres décimaux, mais votre ordinateur (en fait, votre bibliothèque C standard) les stocke sous forme binaire. Vous obtenez des effets secondaires de cette transition:

_>>> print len(repr(0.1))
19
>>> print repr(0.1)
0.10000000000000001
_

L’explication de cette situation se trouve dans ce chapitre du tutoriel python.

Une solution consisterait à utiliser un type qui suit spécifiquement les nombres décimaux, comme python decimal.Decimal :

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

D'autres réponses ont déjà indiqué que la représentation des nombres flottants est une question épineuse, pour le moins.

Puisque vous ne donnez pas assez de contexte à 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 (à partir de 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 tiré de mon invite (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? la décimale est dans python stdlib depuis 2.4, avec des ajouts dans python 2.6.

J'espère que ça aide, Francesco

3
Francesco

Je sais que c'est trop tard, mais pour ceux qui viennent ici pour la première fois, j'aimerais proposer une solution. J'ai une valeur float 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

La sortie est

1.0,data/2.jpg

Vous pouvez modifier cet exemple de formatage selon votre convenance.

0
Harsh Wardhan