6

入力後

from decimal import *
getcontext().prec = 6
Decimal (1) / Decimal (7)

私は値を取得します

Decimal('0.142857')  

ただし、入力するDecimal (1.0/7)と取得します

Decimal('0.142857142857142849212692681248881854116916656494140625')
4

1 に答える 1

11

1.0 / 7は、17桁の精度で2進浮動小数点数を計算します。これは、Decimalコンストラクターがそれを認識する前に発生します。

>>> d = 1.0 / 7
>>> type(d)
<type 'float'>
>>> d.as_integer_ratio()
(2573485501354569, 18014398509481984)

2進数の小数部2573485501354569/18014398509481984は、53ビットの精度を使用して2進数の浮動小数点を取得できるのと同じくらい近いです。正確には1/7ではありませんが、かなり近いです。

次に、Decimalコンストラクターは、2進数の小数部を必要な数の場所に変換して、正確な10進数に相当するものを取得します。あなたが見ている結果は、2573485501354569/18014398509481984を正確に評価したときに得られるものです。

>>> from decimal import Decimal, getcontext
>>> getcontext().prec = 100
>>> Decimal(2573485501354569) / Decimal(18014398509481984)
Decimal('0.142857142857142849212692681248881854116916656494140625')

学習ポイント1: 2進浮動小数点は、53ビットの精度で2進小数部を計算します。結果は必要に応じて丸められます。

学習ポイント2:Decimalコンストラクターは、2進数の浮動小数点数をロスレスで(丸めなしで)10進数に変換します。これにより、予想よりもはるかに多くの桁の精度が得られる傾向があります(Decimal FAQの6番目の質問を参照してください)。

学習ポイント3:10進モジュールは、すべての数値を正確なものとして扱うように設計されています。計算結果のみがコンテキスト精度に丸められます。2進浮動小数点入力は正確に小数に変換され、数値を使用して計算を行うまでコンテキスト精度は適用されません(詳細については、10進FAQの最後の質問と回答を参照してください)。

エグゼクティブサマリー: 10進モジュールに数値を渡す前に、2進浮動小数点除算を行わないでください。それがあなたの望む精度で仕事をするようにしなさい。

お役に立てれば :-)

于 2012-09-06T01:53:24.733 に答える