Python中不准确的对数

Avi*_*ion 9 python math floating-point

我每天都在我的公司用Python 2.4工作.我使用了标准数学库中的多功能对数函数'log',当我输入log(2**31,2)时,它返回31.000000000000004,这让我感到有点奇怪.

我用2的其他力量做了同样的事情,它完美地运作了.我跑了'log10(2**31)/ log10(2)',我得到了一轮31.0

我尝试在Python 3.0.1中运行相同的原始函数,假设它是在更高级的版本中修复的.

为什么会这样?Python中的数学函数有可能存在一些不准确之处吗?

Mat*_*hen 47

这可以通过计算机算术来实现.它遵循特定的规则,例如IEEE 754,可能与您在学校学到的数学不符.

如果这确实很重要,请使用Python的十进制类型.

例:

from decimal import Decimal, Context
ctx = Context(prec=20)
two = Decimal(2)
ctx.divide(ctx.power(two, Decimal(31)).ln(ctx), two.ln(ctx))
Run Code Online (Sandbox Code Playgroud)

  • 给一个很好的答案+1,但主要是"如果这真的很重要".探测器以较低的精度飞到土星. (26认同)
  • @dwc 如果 OP 已经对 log 函数的结果进行了处理,那将会很重要。那么误差就会变得非常大。就我而言,在我的一个程序中,我这样做了:`a = floor(log(x,b))` 并且程序在前面几行崩溃了,因为 `floor(log(243,3))` 是出来是 4 (5认同)

bay*_*yer 20

您应该阅读"每个计算机科学家应该知道的关于浮点算术的内容".

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

  • 非常感谢。这是一个强大的参考。 (2认同)

pax*_*blo 17

总是假设浮点运算将有他们一些错误,并检查采取的错误兼顾平等(一个百分比值,像0.00001%或固定值像0.00000000001).这种不准确性是给定的,因为并非所有十进制数都可以用固定位数精度的二进制表示.

如果Python使用IEEE754,那么你的特殊情况不是其中之一,因为31应该可以很容易地用单精度表示.这是可能的.然而,它在它需要计算日志的众多步骤之一损失精度2 2 31,仅仅是因为它没有代码来检测类似的两个直接供电的特殊情况.


Nic*_*zet 5

浮点运算永远不会完全正确.对于语言/硬件基础结构,它们返回具有可接受的相对误差的结果.

一般来说,假设浮点运算是精确的,特别是单精度运算是错误的.来自维基百科的"准确性问题"部分浮点文章:)