Python中的不准确对数

16 投票
9 回答
12890 浏览
提问于 2025-04-15 11:57

我在公司每天都在用Python 2.4。最近我用标准数学库里的一个很实用的对数函数'log',当我输入log(2**31, 2)时,它返回了31.000000000000004,这让我觉得有点奇怪。

我用其他2的幂次方做了同样的计算,结果都很正常。我运行了'log10(2**31) / log10(2)',得到了一个整齐的31.0。

我还在Python 3.0.1中试了一下这个原始的函数,以为在更新的版本中这个问题会被修复。

这到底是怎么回事呢?难道Python的数学函数会有一些不准确的地方吗?

9 个回答

18

总是要记住,浮点数运算可能会有一些误差,所以在比较两个浮点数是否相等时,要考虑到这个误差(可以是像0.00001%这样的百分比值,或者像0.00000000001这样的固定值)。这种不准确是正常的,因为并不是所有的小数都能用固定数量的二进制位精确表示。

在你的例子中,如果Python使用的是IEEE754标准,那么31这个数字应该是可以很容易地用单精度表示的。不过,在计算log2231的过程中,可能会因为某些步骤的原因而失去精度,特别是因为它没有专门的代码来处理像2的幂这样的特殊情况。

21

你应该看看《每个计算机科学家都应该知道的浮点运算知识》。

http://docs.sun.com/source/806-3568/ncg_goldberg.html

53

这在计算机运算中是很正常的现象。计算机遵循一些特定的规则,比如IEEE 754,这些规则可能和你在学校学的数学不太一样。

如果这真的很重要,建议你使用Python的decimal类型

示例:

from decimal import Decimal, Context
ctx = Context(prec=20)
two = Decimal(2)
ctx.divide(ctx.power(two, Decimal(31)).ln(ctx), two.ln(ctx))

撰写回答