【问题标题】:Python Decimal module stops adding Decimals to another Decimal once it reaches 1.0Python Decimal 模块一旦达到 1.0 就停止将 Decimals 添加到另一个 Decimal
【发布时间】:2023-01-12 12:11:56
【问题描述】:

我正在使用 python 的 decimal 模块来做一些涉及小数的工作。我有以下代码:

from decimal import *
getcontext().prec = 2  # use two decimal places

counter = Decimal(0)
while counter != Decimal(1000.01):
    print(counter)
    counter += Decimal(0.01)

这应该以 0.01 的增量打印从 0 到 1000.00 的每个数字,但出于某种原因, 数字 0.01 到 0.09 有三位小数(即 0.010 而不是 0.01),在 counter 达到 1.0 后(由于某种原因有一位小数),它完全停止增加并保持在 1.0。输出看起来像这样:

0
0.010
0.020
0.030
0.040
0.050
0.060
0.070
0.080
0.090
0.10
0.11
0.12
...
0.97
0.98
0.99
1.0
1.0
1.0

(repeats 1.0 forever)

我在这里做错了什么?

【问题讨论】:

  • 您应该将字符串传递给Decimal,否则您将失去好处。 Decimal 通常用于避免由floats 引起的舍入错误。如果您传入 float,则在您开始之前已经发生舍入错误。
  • @Axe319 将我传递的所有值转换为 Decimal 在达到 1.0 后仍然会导致相同的错误。尽管它确实解决了小数点后三位的问题。
  • getcontext().prec = 2 并没有按照您的想法行事。精度适用于全部数字,甚至是剩下的小数点。因此,一旦计数器达到 1.0,您就“用完了”所有精度数字。 1.01 将是三位数的精度。

标签: python decimal


【解决方案1】:

精度是针对数量全部的数字,而不是小数点后的数字,对于计算,所以对于 1000.01 你至少需要 6 个。

还可以使用字符串来初始化 Decimal,因为使用 float 对于基数 2 不能很好表示的值来说已经不准确了。

例子:

>>> from decimal import Decimal as d, getcontext
>>> d(0.01)  # don't use float.  It is already inaccurate
Decimal('0.01000000000000000020816681711721685132943093776702880859375')
>>> getcontext().prec  # default precision
28
>>> d(0.01) + d(0.01)
Decimal('0.02000000000000000041633363423')
>>> d('0.01')   # exact!
Decimal('0.01')
>>> getcontext().prec = 6
>>> d(0.01)  # doesn't affect initialization.
Decimal('0.01000000000000000020816681711721685132943093776702880859375')
>>> d(0.01) + d(0.01)  # now the calculation truncates to 6 digits of precision
Decimal('0.0200000')   # note that 2 is the first digit and 00000 are the next 5.
>>> d('0.01') + d('0.01')
Decimal('0.02')

修复 OP 示例:

from decimal import *
getcontext().prec = 6  # digits of precision

counter = Decimal('0')
while counter != Decimal('1000.01'):
    print(counter)
    counter += Decimal('0.01')

【讨论】:

    猜你喜欢
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多