Python 十进制库不精确?[复制]

Python Decimal Library is Imprecise? [duplicate]

提问人:scotty-nukem 提问时间:9/17/2021 最后编辑:wjandreascotty-nukem 更新时间:9/17/2021 访问量:292

问:

我正在阅读 Python Decimal 模块。我需要进行大量精确的计算,通常有很多小数位,随着时间的推移,少量的偏差会累积起来。进入 Decimal 库。

第 1 步:阅读 Decimal 库的介绍(添加粗体):

  • 十进制数可以精确表示。相比之下,像 1.1 和 2.2 这样的数字在二进制浮点数中没有精确的表示。最终用户通常不会期望显示为 3.3000000000000000003,因为它对二进制浮点数所做的那样。1.1 + 2.2

第 2 步:将小数插入 Python。这似乎不精确 - 与浮点计算的差距非常相似。

>>> from decimal import *
>>> 1.1 + 2.2
3.3000000000000003
>>> Decimal(3.3)
Decimal('3.29999999999999982236431605997495353221893310546875')

这是怎么回事?

Python 十进制 浮点精度

评论

2赞 juanpa.arrivillaga 9/17/2021
请仔细阅读文档你认为当你将一个对象传递给构造函数时会发生什么?floatDecimal
0赞 Peter Wood 9/17/2021
您可能需要算法来减少精度误差。
0赞 scotty-nukem 9/17/2021
@Juanpa谢谢,我意识到了我的错误
0赞 Eric Postpischil 9/17/2021
十进制格式只能精确计算十进制结果,即可表示为十进制数字的结果。如果超过它支持或已设置的位数,或者如果执行任何计算的结果无法表示为十进制数字(例如深奥的 1/3),则其精度的行为与其他数字格式类似。

答:

3赞 dan04 9/17/2021 #1

根据文档:

从整数或浮点数构造执行该整数或浮点数值的精确转换。

文字的确切值不是 3.3 = 33/10,而是二进制近似值 3715469692580659 / 250,其确切值是您在屏幕截图中看到的值。如果这不是您想要的,则将 a 而不是 a 传递给构造函数。float3.3strfloat

>>> from decimal import *
>>> Decimal(3.3)
Decimal('3.29999999999999982236431605997495353221893310546875')
>>> Decimal('3.3')
Decimal('3.3')

还要记住,虽然这在表示 1/10、1/100 或 1/1000 等十进制分数时是精确的,但其他分数是近似的(尽管比 更精确)。Decimalfloat

>>> Decimal(1) / Decimal(3)
Decimal('0.3333333333333333333333333333')
>>> _ * 3
Decimal('0.9999999999999999999999999999')

如果这对您来说是一个问题,请使用该类而不是 .FractionDecimal

>>> from fractions import *
>>> Fraction(1) / Fraction(3)
Fraction(1, 3)
>>> _ * 3
Fraction(1, 1)

评论

0赞 scotty-nukem 9/20/2021
谢谢,这很有帮助。尤其是关于分数模块的部分。我没有意识到那是在那里。十进制仍然对我有用。我不需要完美的精度,但我绝对需要比 Float 给我的更多。