web-dev-qa-db-ja.com

フロートを丸めずに文字列に変換する

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

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

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

例えば:

>>> .1
0.10000000000000001

この場合、reprを使用して.1が文字列に変換されます:

>>> repr(.1)
'0.10000000000000001'

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

>>> str(.1)
'0.1'

「丸め」がどのような問題を引き起こしているのか正確にはわかりません。おそらく、出力をより正確に制御する方法として、文字列の書式設定の方が良いでしょうか?

例えば.

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

ドキュメントはこちら

119
John Fouhy
len(repr(float(x)/3))

ただし、これはあなたが考えるほど信頼性が高いとは言えません。

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

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

これが起こる理由についての説明は、pythonチュートリアルの この章 にあります。

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

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

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

あなたはあなたの質問に十分なコンテキストを与えていないので、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

たぶんこれは助けになりますか? 2.4以降、decimalはpython stdlibにあり、python 2.6に追加されています。

これがお役に立てば幸いです、フランチェスコ

3
Francesco

私はこれが遅すぎることを知っていますが、初めてここに来る人のために、私は解決策を投稿したいと思います。フロート値indexと文字列imgfileがあり、あなたと同じ問題がありました。これは私が問題を修正した方法です

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

出力は

1.0,data/2.jpg

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

0
Harsh Wardhan