不使用任何函数计算e ^ x

时间:2009-05-06 02:00:11

标签: c++ math exponential

我们应该使用这种公式计算e ^ x:

e ^ x = 1 +(x ^ 1/1!)+(x ^ 2/2!)......

到目前为止我有这个代码:

while (result >= 1.0E-20 )
{
    power = power * input;
    factorial = factorial * counter;
    result = power / factorial;
    eValue += result;
    counter++;
    iterations++;
}

我现在的问题是,因为阶乘是长型的,我实际上不能存储大于20的数字!所以会发生什么,当程序到达那个点时,程序会输出有趣的数字。

正确的解决方案的X值最多为709,因此应输出e ^ 709:8.21840746155e + 307

该程序是用C ++编写的。

4 个答案:

答案 0 :(得分:32)

x ^ n和n!用n快速增长(分别呈指数级和超指数级)并很快溢出您使用的任何数据类型。另一方面,x ^ n / n!下降(最终),你可以在小的时候停下来。也就是说,使用x ^(n + 1)/(n + 1)的事实! =(x ^ n / n!)*(x /(n + 1))。像这样,说:

term = 1.0;
for(n=1; term >= 1.0E-10; n++)
{
    eValue += term;
    term = term * x / n;
}

(代码直接输入此框,但我希望它可以正常工作。)

编辑:注意术语x ^ n / n!是,对于大x,增加一段时间然后减少。对于x = 709,它在降低到0之前上升到~1e + 306,这正好在double可以处理的范围内(double的范围是〜1e308和{{1}推动它,但term*x工作正常。当然,您的最终结果 e x 比任何条款都要大,所以假设您使用的数据类型足以容纳结果,那么您将成为细

(对于x = 709,如果您使用long double,则只能使用double,但它不适用于710.)

答案 1 :(得分:4)

如果您将factorial的类型从long long更改为double会怎样?

答案 2 :(得分:2)

我可以想到另一个解决方案。 让pow(e,x) = pow(10, m) * b b>=1< 10,然后

m = trunc( x * log10(e) )

log10(e)中的常数因素。

b = pow(e,x)/pow(10, m ) = pow(e,x)/pow(e,m/log10(e)) = pow (e,x-m/log10(e))

通过这个你得到:

z = x-m/log10(e)

将介于0到3之间,然后使用SreevartsR给出的b = pow(e,z)

并且最终答案是

b是基数(有效数字),m是尾数(数量级)。

这比SreevartsR方法更快,你可能不需要使用高精度。

祝你好运。

这甚至适用于x小于0且负值较大的情况,在这种情况下,z将介于0到-3之间,这将比任何其他方法更快。

由于z是-3到3,如果你需要前20个有效数字,那么pow(e,z)表达式最多只能评估37个术语,因为3 ^ 37/37! = ~3.2e-26。

答案 3 :(得分:1)

您在此处介绍的是Horner scheme用于计算多项式的应用。