原谅我提出这个问题的方式以及我提出的事实中显而易见的天真。
数学家通常使用因为它是理论上最简单/最简单的基础(由于微积分)。但是计算机似乎以二进制形式完成所有工作,因此在计算机上进行计算的速度是否比?2**x
Math::exp(x)
原谅我提出这个问题的方式以及我提出的事实中显而易见的天真。
数学家通常使用因为它是理论上最简单/最简单的基础(由于微积分)。但是计算机似乎以二进制形式完成所有工作,因此在计算机上进行计算的速度是否比?2**x
Math::exp(x)
Answers:
因为这是CS,而不是Stackoverflow,所以我假设您要问一个关于数值分析的问题,(为了简化起见)特别是IEEE-754浮点数。在这种情况下,问题的答案部分取决于您“更轻松”的含义,部分取决于系统的细节。
我所知的现代CPU都没有内置可以完全满足操作(此后我们将其称为C的常规名称)或()的指令的指令。它们都使用库函数来实现。2 Xexp
exp2
与用于先验运算的所有数值方法一样,有一些特殊情况需要考虑:
exp(NaN) = NaN
exp(+Inf) = +Inf
exp(-Inf) = 0
但是,还有另一件事使问题稍微复杂一些:有用的域很小。对于binary32,exp(x)
如果左右,则下溢;如果左右,则上溢。不寻常的超越行动,我们也可以忽略低于正常情况下,由于是从没有区别,如果是低于正常。上面的所有情况也适用于,除了域略有不同。x > 88.7exp(x)
1.0
x
exp2
您的直觉是正确的,因为大多数实现都可以计算。但是,与其余计算相比,通过乘法运算的成本微不足道。典型的方法使用带有元素的预计算表:1 Kexp2
其中是的整数部分,表包含范围内的所有值,是多项式近似值(对于32 )在。在部分是便宜的,因为它只是操纵指数。是一个查询表。因此,可能是操作的昂贵部分。X Ť 2 Ĵ / ķ Ĵ [ 0 ,ķ )P 2 X [ 0 ,12nTP
为了完整性,我应该指出英特尔x86 FPU包含一条称为的指令f2xm1
,该指令为范围内的计算。但是,在现代CPU上,这是一条相当昂贵且非流水线的指令,因此强烈建议您不要使用它。正如《英特尔优化参考手册》第3.8.5节正确指出的那样:X [ - 1 ,1 ]
尽管x87支持先验指令,但在许多情况下,先验功能的软件库实现可以更快。
编辑:在评论中已指出,我应该解释IEEE 754-2008中使用的一些新术语。自1985年和1987年以来,某些语言已经发生了变化,并且大多数人对旧术语更加熟悉。
术语“ binary32”和“ binary64”是32位和64位二进制浮点数的新名称,旧标准分别将其称为“单”和“双”。
术语“非正规数”代替了先前的术语“非正规数”或“非正规数”。
由于2 ^ x = e ^(x * ln 2)和e ^ x = 2 ^(x * log2(e)),所以您不会期望有太大差异。
对于x接近零的情况,通常会使用多项式e ^ x = 1 + x + x ^ 2/2 + x ^ 3/6 ... 。显然,2 ^ x的计算速度很小。“ x接近0”通常是x的值,其中sqrt(1/2)<= e ^ x <= sqrt(2)。限制x的范围可确保不必将多项式选择得太高。
对于更大的x,通常可以通过让x = x'+ x''来计算2 ^ x,其中x'是整数,-0.5 <= x''<= 0.5。然后,通过使用正确的位模式构造浮点数来计算2 ^ x',对于小x使用e ^ x方法来构造2 ^ x''。在这里,2 ^ x快一点。此外,如果x较大(例如x = 100.3),则仅将x乘以log2(e)会引入不可接受的舍入误差(因为小数位少很多),因此需要格外小心。
并希望有一个好的库函数会注意,无论什么舍入误差,只要x <= y,e ^ x <= e ^ y和2 ^ x <= 2 ^ y。实现这种事情可能很棘手。
您必须了解计算机上的数学运算是由不同的软件以不同的方式完成的,希望能给出一致的答案。查看大多数软件,我认为计算机的运行情况良好-计算机,即使是0 ^ 0,也可以很长的时间计算出答案。问题在于特殊情况涉及“识别”,这在数字计算机中不是免费发生的。这意味着,只有在拥有答案的情况下才能“最快速”地进行优化,才会发生优化。但是在那种情况下,它将发生得非常好。还要注意,可能必须进行几种不同的识别才能获得正确的答案。这被称为速度优化级别,这在大多数称为GNU“ C”的软件的基础上已达到最大程度的专业化。这是因为此处使用的是软件之间,软件之间以及计算机之间的运行时间的微小差异作为质量验收指标。在其他解释器中,通常仅当“零标志”出现时,因为先前计算的副作用将加快识别的速度。例如0 * x => C0。