math.exp(2) 和 math.e**2 之间的区别 [重复]
Posted
技术标签:
【中文标题】math.exp(2) 和 math.e**2 之间的区别 [重复]【英文标题】:Difference between math.exp(2) and math.e**2 [duplicate] 【发布时间】:2015-06-10 12:54:13 【问题描述】:在编程时,我注意到 math.exp(2) 和 math.e**2 的结果之间存在差异。正如您在下面看到的,在计算 e^1 时不会出现这种差异。
我不是经验丰富的程序员,我想知道为什么会有所不同?
我认为这与四舍五入有关。 python 文档说math.exp(x)
返回e**x
,但这似乎并不完全正确。那么math.exp(x)
操作为什么与math.e**x
不同呢?
>>> math.exp(1)
2.718281828459045
>>> math.e**1
2.718281828459045
>>> math.exp(1)==math.e**1
True
>>> math.exp(2)
7.38905609893065
>>> math.e**2
7.3890560989306495
>>> math.exp(2)==math.e**2
False
>>> math.exp(100)
2.6881171418161356e+43
>>> math.e**100
2.6881171418161212e+43
>>> math.exp(100)==math.e**100
False
【问题讨论】:
相关:***.com/a/15322395/1639625 我的猜测:math.exp
是在 c
(甚至在硬件中)实现的,因此浮点行为略有不同。
投票重新开放。这里发生的不仅仅是“浮点数不准确”。特别是,正如两个答案所解释的那样,有充分的理由期望 exp(x)
比 e**x
更准确。
【参考方案1】:
由于功能实现的不同而有所不同。由于浮点的性质,两者都不是完美的。
**
操作符是在floatobject.c中实现的,包含了很多特殊情况,但是这里都没有调用,所以最终达到了标准C的pow
函数。 math.pow 函数最终会做同样的事情。
exp
函数是同名 C 函数的直接包装,用 mathmodule.c 中的宏定义。
碰巧, exp 更精确(两个结果都匹配,在浮点允许的精度范围内,我在 bc 中计算的高精度答案)。很可能是因为在 pow 内部,它正在计算您作为第一个参数传递的双精度 e
值的扩展精度对数,该值略小于 1。
根本问题是math.e
,也就是你计算幂的数字,是:
2.718281828459045 09079559829...
而 e 的真正价值是
2.718281828459045 23536028747...
当您使用pow
或**
时,此错误会更加复杂,而如果您使用exp
,由于算法的细节,它可能不会(或可能在内部使用更高的精度值)它使用。
【讨论】:
我的理解:什么是 bc? @rosie2go 这是一个适用于 unix 和 linux 系统的任意精度命令行计算器 - 因为它是任意精度,我可以将其设置为 50 位计算并将该结果与 python 浮点结果进行比较。 所以整数 1 变成 0.9999999999999999468198834395860075119344401173293590545654296875 当你把它改成一个浮点数? @rosie2go 不,关键是e
变成了一个稍微小的数字,因此这个数字的对数不等于 1。而我之前列出的值是 C long double,而不是一个蟒蛇浮子。我已经编辑了我的答案以更清楚。【参考方案2】:
exp(x)
的实现水平远低于e**x
。它本质上是 libc 中函数的包装器。所述函数可能(在某种程度上)使用Taylor series 扩展来直接计算值(或者可能是其他一些数学方法,我不确定)。
另一方面,e**x
正在获取一个数字并将其提升为幂。这是一种完全不同的策略,在大多数情况下可能不太精确。将数字提高到幂很难精确地做到。
【讨论】:
以上是关于math.exp(2) 和 math.e**2 之间的区别 [重复]的主要内容,如果未能解决你的问题,请参考以下文章