指数函数的泰勒级数exp(-x)

时间:2013-10-07 21:31:55

标签: exponential

我一直致力于Taylor系列的程序,并使用long double作为数字格式来计算大数。我的程序对于积极的指数来说非常好,但是当它指向负指数时它会失败。问题是,当我为某些x计算exp(-x)时,我得到非常大的正数。这背后可能是什么原因?感谢您的帮助。你可以在这里看到我的代码:

#include <stdio.h>
#include <math.h>
//We need to write a factorial function beforehand, since we
//have factorial in the denominators.
//Remembering that factorials are defined for integers; it is
//possible to define factorials of non-integer numbers using
//Gamma Function but we will omit that.
//We first declare the factorial function as follows:
long double factorial (double);
//Long long integer format only allows numbers in the order of 10^18 so 
//we shall use the sign bit in order to increase our range.
//Now we define it,
long double
factorial(double n)
{
//Here s is the free parameter which is increased by one in each step and
//pro is the initial product and by setting pro to be 0 we also cover the
//case of zero factorial.
    int s = 1;
    long double pro = 1;
    if (n < 0)
        printf("Factorial is not defined for a negative number \n");
    else {
    while (n >= s) { 
    pro *= s;
    s++;
    }
    return pro;
    }
}

int main ()
{
    long double x[13] = { 1, 5, 10, 15, 20, 50, 100, -1, -5, -10, -20, -50, -100};
//Here an array named "calc" is defined to store 
//the values of x.

//int k;
////The upper index controls the accuracy of the Taylor Series, so
////it is suitable to make it an adjustable parameter. 
int p = 135;
long double series[13][p];
long double sum = 0;
int i, k;
for (i = 0; i <= 12;i++) {
for (k = 0; k <= p; k++){
    series[i][k] = pow(x[i], k)/( factorial(k));
    sum += series[i][k];
}
printf("Approximation for x = %Lf is %Lf \n", x[i], sum);
}
printf("%Lf \n", factorial(100));
}

3 个答案:

答案 0 :(得分:2)

你没有将你的金额归零。您只是将每个新结果添加到上一个。

添加sum = 0;作为第一个for循环中的第一个语句。

道德:始终为应该是一个函数创建一个函数。在这种情况下,编写一个单独的exp_taylor()函数,而不是仅仅将其写入内联。

答案 1 :(得分:2)

这只是数值分析的数学主题。 e^x的MacLaurin系列收敛于所有x,但让我们看看为什么它对e^(-10)没用。

e^x = 1 + x + x^2/2 + x^3/6 + x^4/24 + x^5/120 + x^6/720 + x^7/5040 + ... +x^n/n! + ...

e^(-10) = 1 - 10 + 100/2 - 1000/6 + 10000/24 -100000/120 + ...

该系列中最大的术语是什么? 10^10/10!,大约为2755.7319224e^(-10)大约0.00004539992的真正价值是什么?加起来这个系列在整个过程中会丢失9位精度,你根本就没有。

如果你找到了e^(10)并采取了倒数,那你就相当安全了。如果您通过乘以(1 / e)10次直接计算e ^( - 10),那么您也是安全的。但任何具有交替术语的系列都可能会导致这些问题。

即使是范围有限的功能,MacLaurin系列也未在实践中使用。例如,首先采用trig函数的参数,并使用周期性和trig标识将参数减少到区间0 < θ < π/4。然后,经常应用Chebychev近似来均匀地减少误差。在其他情况下,连续分数和Pade近似值优于Trigonometric系列。贝塞尔函数最好通过向后递归来完成。

看一本好的数值分析书。 Forman Acton的通常工作的数值方法是老式的,但很好。

答案 2 :(得分:0)

在计算每个系列后,您需要将总和重置为零:

int main ()
{
  long double x[13] = { 1, 5, 10, 15, 20, 50, 100, -1, -5, -10, -20, -50, -100}; 
  const int p = 135;
  long double series[13][p];
  int i, k;
  for (i = 0; i <= 12;i++) {
    long double sum = 0;  // LOOK HERE
    for (k = 0; k <= p; k++){
      series[i][k] = pow(x[i], k)/( factorial(k));
      sum += series[i][k];
    }
    printf("Approximation for x = %Lf is %Lf \n", x[i], sum);
  }
}

另请注意,您正在扩展x = 0,并且可能会出现远远超过0的x的重大错误。