floatを丸めずに文字列に変換する


88

説明する必要がない理由で、floatを文字列に変換してlen()でカウントする必要があるプログラムを作成しています。ただし、str(float(x))を使用すると、xが文字列に変換されるときに丸められ、全体が破棄されます。誰かがそれに対する修正を知っていますか?知りたい場合に使用するコードは次のとおりです。

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

2
xが元々strの場合、なぜキャストなのか?
Vinko Vrsalovic、2009

1
-1:のさまざまな値に必要な出力の例はありませんx。例がなければ、私たちは問題が何であるかを推測することしかできません。
S.Lott、2009

回答:


129

浮動小数点数を処理する場合、何らかの形の丸めが避けられないことがよくあります。これは、基数10で正確に表現できる数値が、基数2(コンピューターが使用する)で常に正確に表現できるとは限らないためです。

例えば:

>>> .1
0.10000000000000001

この場合、.1は次のようにして文字列に変換されていますrepr

>>> repr(.1)
'0.10000000000000001'

この問題を回避するためにstr()を使用すると、pythonは最後の数桁を切り落とすと思いますが、これは何が起こっているのかを理解する代わりにしない部分的な回避策です。

>>> str(.1)
'0.1'

「丸め」がどのような問題を引き起こしているのか正確にはわかりません。おそらく、出力をより正確に制御する方法として、文字列のフォーマットを使用するほうがよいでしょう。

例えば

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

ドキュメントはこちら


12
len(repr(float(x)/3))

しかし、これはあなたが思うほど信頼できるとは言えない。

浮動小数点数は10進数として入力/表示されますが、コンピューター(実際には、標準Cライブラリ)は2進数として格納します。この移行により、いくつかの副作用が発生します。

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

これが発生する理由の説明は、Pythonチュートリアルのこの章にあります。

解決策は、pythonのように、特に10進数を追跡するタイプを使用することですdecimal.Decimal

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

除算の結果であるフロートの使用方法に関する良い記事:stackoverflow.com/questions/2958684/python-division
Trutane

3

控えめに言っても、浮動小数点数の表現は厄介な問題であると他の回答はすでに指摘しています。

あなたの質問では十分なコンテキストを与えていないので、decimalモジュールがあなたのニーズに役立つかどうかわかりません:

http://docs.python.org/library/decimal.html

特に、(ドキュメントから)取得したい精度を明示的に指定できます。

>>> 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')

私のプロンプトからの簡単な例(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

多分これは助けることができますか?decimalは2.4以降、python 2.6で追加されたPython stdlibに含まれています。

これが役立つことを願って、フランチェスコ


0

これは遅すぎることはわかっていますが、初めてここに来る人のために、解決策を投稿したいと思います。float値indexとstringがimgfileあり、あなたと同じ問題がありました。これは私が問題を修正した方法です

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

出力は

1.0,data/2.jpg

このフォーマットの例は、必要に応じて変更できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.