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 位精度。这发生在Decimal构造函数看到它之前:

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

二进制小数 2573485501354569 / 18014398509481984 与使用 53 位精度的二进制浮点数一样接近。它不完全是 1/7,但非常接近。

然后 Decimal 构造函数将二进制小数转换为所需的尽可能多的位置,以获得精确的十进制等效值。您看到的结果就是您在评估 2573485501354569 / 18014398509481984 时得到的结果:

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

学习点 1: 二进制浮点将二进制分数计算到 53 位精度。必要时对结果进行四舍五入。

学习点 2: Decimal构造函数将二进制浮点数无损转换为小数(无舍入)。这往往会导致比您预期的更多位数的精度(请参阅小数常见问题解答中的第 6 个问题)。

学习点3:十进制模块旨在将所有数字视为精确。只有计算结果会被四舍五入到上下文精度。二进制浮点输入被精确地转换为十进制,并且在您使用数字进行计算之前不会应用上下文精度(有关详细信息,请参阅十进制常见问题解答中的最终问题和答案)。

执行摘要: 在将数字交给十进制模块之前不要进行二进制浮点除法。让它以您想要的精度完成工作。

希望这可以帮助 :-)

于 2012-09-06T01:53:24.733 回答