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 之间的区别 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Math()对象

学习Java之Math和Random类

Math对象的属性和方法

Java之Math类

Java 中 Math.exp 函数的局限性

javascript Math对象