C中的泰勒级数逻辑

时间:2015-07-23 00:22:04

标签: c logic approximation taylor-series

我正在研究使用泰勒系列近似e ^ x的项目,其中x是用户输入的值。我们给出的测试值是x = .5,x = 1.0和x = 1.5。目标是获得输出应该是一个表,其中每个迭代创建一个系列的循环,第一列包含迭代次数,第二列包含理论值(基于exp(x)) ),第三个总和,以及理论值和迭代值之间的第四个差异。

我目前的代码如下。就目前而言,我的逻辑有一些漏洞,因为代码构建和运行,但输出不正确。如果我要抓住我的问题,我认为我的求和不是从正确的位置开始(1),并且前两个项是错误的(1 + x +(x ^ 2/2!)+(x ^ 3/3!)......等等。

我应该使用什么逻辑与我拥有的相比?感谢。

//cs 1325
// Dean Davis
// Dr. Paulk
// series convergence homework.

#include <stdio.h>
#include <float.h> // need it for FLT_EPSILON
#include <math.h>


unsigned long factorial(int); // function will calculate the factorial 

int main()
{
    int n = 0;
    unsigned long fact;  // this variable will hold the factorial value
    float x; // this will be the value read in from the user
    double theoval; // this will hold the theoretical value of e^x
    double holder; // will hold the value of the nth term
    double total = 0; // will accumulate the total summation
    double diff;  // will hold the sifferential between theoretical value and the summation
    puts("Please enter a numerical value greater than zero: "); // request input
    scanf_s("%f", &x); // read it in
    theoval=exp(x); // calc the theoretical value

    printf("# Iter      e^x       Sum       Diff\n");
    printf("-------   -------     -------   -------\n"); // set up the output

    while ((theoval - total) >= FLT_EPSILON) //the loop to continue to sum the summation
    {
        fact = factorial(n); // calls the factorial function
        holder = (pow(x, n)) / fact; // calculates the term n
        total = total + holder;  // adds to the sum
        diff = theoval - total;  // calc the diff
        printf(" %-9d%-12.6f%-14.6f%-10.8f\n", n, theoval, total, diff); // output it
        if ((theoval - total) >= FLT_EPSILON) // if it is smaller, then we don't wan't to increment n
            continue;
        else
            n++;
    }

    printf("The number of iterations required for convergence is: %d\n", n); // out put this line

}


unsigned long factorial(int n)
{
    unsigned long int fact=n; 
    if (n == 0) // if n is zero, 0!=1
        return 1;
    else // so long as it is not, then we can calculate it like this
    {
        n--; // decrement it
        for (n; n > 0; n--)
        {
            fact = fact*n; // multiply the next number by the product of all the preceding terms
        }
        return fact;
    }
}

2 个答案:

答案 0 :(得分:2)

你的主要问题在于:

    if ((theoval - total) >= FLT_EPSILON) // if it is smaller, then we don't wan't to increment n
        continue;
    else
        n++;

逻辑是倒退的,也是不必要的。它是向后的,因为你完全避免在你想要递增它的情况下增加n,这是不必要的,因为在其他情况下你无论如何都要退出循环,因为while表达式是假的。只需无条件地增加n

这个表达也有点怀疑:

(theoval - total) >= FLT_EPSILON

FLT_EPSILON与可表示的float接近1.0 之间的间距相关。不同位置的间距不同,因此将其用作绝对误差界限是没有意义的。由于泰勒级数以余数项的形式具有明确定义的误差界限,我建议改为计算当前n的余数项的最大可能值,并且如果该边界误差值的比率则退出到当前的总和小于一些相当小的值,例如可能0.00001

答案 1 :(得分:2)

除了def most_common_letter(string) arr1 = string.chars arr2 = arr1.max_by(&:count) end 的问题之外,您处理因子的方式存在问题。这些价值观变得很快。 13! = 6227020800,它超出了32位int的范围,因此任何超过13次迭代都会得到无效结果。

你真的不想计算因子,因为你想计算下一个词。每个字词都是前一个字词的if ((theoval - total) >= FLT_EPSILON)倍,因此您无需明确计算x / nx^n即可计算每个字词。

n!