Python中Decimal库的精度

5

Decimal的文档页面上看,我认为一旦我们使用十进制数进行计算,结果将是没有任何浮点误差的正确结果。

但是当我尝试这个等式时

from decimal import Decimal, getcontext
getcontext().prec = 250

a = Decimal('6')
b = Decimal('500000')

b = a ** b
print('prec: ' + str(getcontext().prec) + ', ', end='')
print(b.ln() / a.ln())

它给我不同的结果!

enter image description here

我想要计算以六进制表示时6**500000数位的数量,所以我的期望结果应该是int(b.ln() / a.ln()) + 1,即500001。但是,当我将精度设置为250时,它给我错误的结果。我该怎么解决呢?

此外,如果我想输出结果时避免使用科学计数法(如5E+5),我该怎么做?


2
decimal可调节的精度,而不是无限精度。它说的是“正确舍入的十进制浮点运算”,而不是“未舍入的实数运算”。 - user2357112
请勿上传文本/代码/数据/错误的图像来提问 - 相反,请将其作为格式化的代码块粘贴。谢谢! - Michael Delgado
3个回答

2
这段文档明确展示了getcontext()的参数。

enter image description here

当您简单地执行getcontext()时,它可以显示其内置参数。
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])

当您可以更改getcontext().prec = 250时,它只能覆盖prec值。

enter image description here

主要影响结果的是在精度值后面的四舍五入参数,这是内置参数 round=ROUND_HALF_EVEN。我想把它改成 None,但这可能会出错。

enter image description here

所以它可以澄清,无论我们做什么,由于“四舍五入”参数的存在,它都必须稍微改变。
注意:您的结果也可能受到其他内置参数的影响。

2
如果您需要非常精确或符号化的数学计算,或者遭遇IEEE 754浮点别名问题,请查看SymPy。
>>> from sympy import log, N
>>> expr = log(6**50000) / log(6)
>>> N(expr)
50000.0000000000

1
Decimal.ln() 的文档说明如下:
返回操作数的自然对数(以 e 为底)。结果使用 ROUND_HALF_EVEN 舍入模式进行正确舍入。
当您更改精度时,将计算数字的更多位数,然后将它们向下舍入而不是向上。需要对数字进行舍入,因为它不一定在指定的精度范围内,甚至可能根本不是有理数。
有关以科学计数法输出结果,请参见此问题的答案

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接