2009-08-23 24 views
60

私は、説明が不要な理由から、浮動小数点数をlen()で数えられる文字列に変換する必要があるプログラムを作っています。しかし、str(float(x))は、文字列に変換されたときにxが丸められ、全体をスローします。誰かがそれについての修正を知っていますか?私は、これはあなたが思うほど信頼性がないことを言わなければならないしかし浮動小数点数を丸めずに文字列に変換する

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

xはもともとstrのであれば フランチェスコ、なぜキャスト? –

+1

-1: 'x'の異なる値に必要な出力例はありません。例がなければ、問題の内容を推測することしかできません。 –

答えて

92

丸めのいくつかの形がしばしば避けられません。これは、基数10で正確に表現できる数値は、基数2(コンピュータが使用する)で常に正確に表現できないためです。例えば

:この場合

>>> .1 
0.10000000000000001 

、あなたはreprを使用して文字列に変換0.1を見ている:

>>> repr(.1) 
'0.10000000000000001' 

あなたが使用している場合、私は最後の数桁オフのpythonチョップを信じますこの問題を回避するにはstr()を使用しますが、それは何が起こっているのかを理解することに代わる部分的な回避策です。

>>> str(.1) 
'0.1' 

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

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

Documentation here

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

: ここであなたが知りたい場合に使用されているコードです。

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

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

これがなぜ起こるかについての説明は、Pythonのチュートリアルのthis chapterです。

ソリューションは、特にPythonのdecimal.Decimalのように、小数点以下の数字を追跡タイプを使用することです:浮動小数点数を扱うとき

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

小数点以下は+1です。 –

+0

部門から浮動小数点の結果を扱う方法に関する良い記事:https://stackoverflow.com/questions/2958684/python-division – Trutane

3

浮動小数点数の表現は、言い表せないほど難しい問題であることを既に指摘しています。

あなたがあなたの質問に十分なコンテキストを与えていないので、decimalモジュールは、ニーズのために有用であることができれば、私は知ることができない。とりわけ

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

あなたが明示的に精度を指定することができます(docsから入手したい):

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

おそらくこれが役立つでしょうか? 10進数は2.4よりPython stdlibにあり、Python 2.6では追加されています。このことができます

希望、

関連する問題