9

我们应该使用这种公式计算 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++;
}

我现在的问题是,由于阶乘是 long long 类型,我不能真正存储大于 20 的数字!所以发生的事情是程序在到达那个点时输出有趣的数字..

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

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

4

4 回答 4

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,它会上升到 ~1e+306,然后下降到 0,这只是double可以处理的极限(double的范围是 ~1e308 并将term*x其推过),但long double工作正常。当然,您的最终结果e x大于任何项,因此假设您使用的数据类型足够大以容纳结果,您会没事的。

(对于 x=709,只要使用 就double可以不用使用term = term / n * x,但它不适用于 710。)

于 2009-05-06T02:10:24.203 回答
4

如果将factorialfrom的类型更改为long longto会发生什么double

于 2009-05-06T02:04:30.817 回答
2

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

m = trunc( x * log10(e) )

其中 inlog10(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 之间,然后b = pow(e,z)按照 SreevartsR 给出的使用。

最后的答案是

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

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

祝你好运。

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

由于 z 是 -3 到 3,并且如果您需要前 20 个有效数字,则 pow(e,z) 表达式只能从 3^37/37 开始计算多达 37 个项!= ~ 3.2e-26。

于 2009-05-06T10:53:43.430 回答
1

您在这里介绍的是霍纳方案在计算多项式方面的应用。

于 2009-05-06T08:51:17.063 回答