4

'5.74536541'リストがあり、フロートに変換する特定の数値が含まれています。

Python 3 を使用して印刷して("%0.2f" % (variable))いますが、常に 5.74 ではなく 5.75 が印刷されます。

誰が気にかけているのかはわかりますが、これは通貨換算プログラム用であり、通貨を切り上げ/切り下げしたくありませんが、正確には.

丸めないようにするだけでなく、小数点以下2桁を維持するにはどうすればよいですか?

4

5 に答える 5

9

あなたが言及したような丸め誤差のため、通貨に浮動小数点数を使用しないでください。

あなたの最善の策は、丸めと切り捨てがどのように機能するかを完全に制御できる固定精度を使用することです。decimalドキュメントから:

>>> from decimal import *
>>> getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
    capitals=1, flags=[], traps=[Overflow, DivisionByZero,
    InvalidOperation])

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

すべての通貨ベースの値をDecimals高精度で内部的に表現する必要があります (この場合、標準レベルの精度で問題ありません。そのままにしておいてくださいprec!)。適切にフォーマットされたドルとセントの値をユーザーに出力したい場合は、このlocaleモジュールを使用するのが簡単な方法です。

印刷するときは注意してください。表示のために正しい桁数に量子化する必要があります。そうしないと、丸めがコンテキストDecimalに基づいていません。このステップは、最終表示または単一の最終値に対してDecimalのみ実行する必要があります。すべての中間ステップでは、操作を可能な限り正確にするために、高精度の s を使用する必要があります。quantizeDecimal

>>> from decimal import *
>>> import locale
>>> locale.setlocale(locale.LC_ALL, '')
'en_AU.UTF-8'
>>> getcontext().rounding = ROUND_DOWN
>>> TWOPLACES = Decimal(10) ** -2
>>> var = Decimal('5.74536541')
Decimal('5.74536541')
>>> var.quantize(TWOPLACES)
Decimal('5.74')
>>> locale.currency(var.quantize(TWOPLACES))
'$5.74'
于 2012-12-04T03:46:26.590 に答える
4

通貨と正確性の問題を扱っている場合はfloat、を使用しないでくださいdecimal

于 2012-12-04T03:46:45.833 に答える
1

数 mod 0.01 を取り除く

すなわち

rounded = number - (number % 0.01)

その後、以前と同じように印刷します。

つまり、切り捨ては正確ではありません。丸め誤差スキームを悪用して、銀行から古いお金を盗もうとしていますか?

于 2012-12-04T03:49:28.170 に答える
1

浮動小数点値は「有用な近似値」として知られています。浮動小数点数を四捨五入したり、切り捨てたりしても、結果が浮動小数点値の場合小数点以下何桁まであるかを判断することはできません。

通貨に浮動小数点値を使用しないでください。pydoc decimalたとえば、 を参照してください。Python の decimal モジュールは、10 進固定小数点演算と 10 進浮動小数点演算をサポートしています。

Python のドキュメントでは、 float の丸めについて警告しています。

注 float に対する round() の動作は驚くべきものです。たとえば、round(2.675, 2) は、予想される 2.68 ではなく 2.67 を返します。これはバグではありません。これは、ほとんどの小数が float として正確に表現できないという事実の結果です。

注意しないと、インタープリター プロンプトに表示される値に惑わされてしまいます

Python は、マシンによって格納された 2 進近似の真の 10 進値に対する 10 進近似のみを出力します。

これは、本当の意味で幻想であることを認識することが重要です。マシンの値は正確に 1/10 ではなく、実際のマシン値の表示を丸めているだけです。この事実は、これらの値を使って計算しようとするとすぐに明らかになります

于 2012-12-04T03:46:50.560 に答える
-2

数値が文字列の場合は、文字列を小数点以下 2 文字だけに切り捨ててから、浮動小数点数に変換します。それ以外の場合は、10^n (n は小数点以下の桁数) を掛けてから、float を 10^n で割ります。

于 2012-12-04T03:43:58.467 に答える