我们应该使用这种公式计算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 ++编写的。
答案 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用于计算多项式的应用。