我试图计算出泰勒级数,误差最大,也就是说,我的误差需要小于。我可以修改for循环中的x+=以得到不同的结果。我试了好几个数字,但从来没有变成小于0.001的错误。

#include <stdio.h>
#include <math.h>

float cosine(float x, int j)
{
    float val = 1;
    for (int k = j - 1; k >= 0; --k)
        val = 1 - x*x/(2*k+2)/(2*k+1)*val;
    return val;
}

int main( void )
{
   for( double x = 0; x <= PI/4; x += 0.9999 )
   {

       if(cosine(x, 2) <= 0.001)
       {
           printf("cos(x) : %10g    %10g    %10g\n", x, cos(x), cosine(x, 2));
       }
       printf("cos(x) : %10g    %10g    %10g\n", x, cos(x), cosine(x, 2));
    }

    return 0;
}

我也在为cos(x)做这个。对于这部分,10^-3
float exponential(int n, float x)
{
    float sum = 1.0f; // initialize sum of series

    for (int i = n - 1; i > 0; --i )
        sum = 1 + x * sum / i;

    return sum;
}

int main( void )
{
    // change the number of x in for loop so you can have different range
    for( float x = -2.0f; x <= 2.0f; x += 1.587 )
    {
        // change the frist parameter to have different n value
        if(exponential(5, x) <= 0.001)
        {
            printf("e^x = %f\n", exponential(5, x));
        }
    printf("e^x = %f\n", exponential(5, x));
    }

    return 0;
}

但是每当我更改for循环中的项数时,它总是有一个大于1的错误。如何将其更改为错误小于x ∈ [-pi/4, pi/4]
谢谢!

最佳答案

我的理解是,为了提高精度,你需要考虑泰勒级数中的更多项。例如,考虑当
你试图用泰勒级数来计算e(1)。
$e(x)=\sum\limits{n=0}^{\infty}frac{x^n}{n!}$
我们可以考虑e(1)展开式中的前几个项:

n             value of nth term           sum
0        x^0/0! = 1                   1
1        x^1/1! = 1                   2
2        x^2/2! = 0.5                 2.5
3        x^3/3! = 0.16667             2.66667
4        x^4/4! = 0.04167             2.70834

你应该注意两件事,首先,当我们加上更多的项,我们越来越接近e(1)的精确值,而且连续和之间的差异越来越小。
因此,e(x)的实现可以写成:
#include <stdbool.h>
#include <stdio.h>
#include <math.h>

typedef float (*term)(int, int);
float evalSum(int, int, int, term);
float expTerm(int, int);
int fact(int);
int mypow(int, int);
bool sgn(float);

const int maxTerm = 10;         // number of terms to evaluate in series
const float epsilon = 0.001;    // the accepted error

int main(void)
{
    // change these values to modify the range and increment
    float   start = -2;
    float   end = 2;
    float   inc = 1;

    for(int x = start; x <= end; x += inc)
    {
        float value = 0;
        float prev = 0;

        for(int ndx = 0; ndx < maxTerm; ndx++)
        {
            value = evalSum(0, ndx, x, expTerm);

            float diff = fabs(value-prev);
            if((sgn(value) && sgn(prev)) && (diff < epsilon))
                 break;
            else
                 prev = value;
        }

        printf("the approximate value of exp(%d) is %f\n", x, value);
    }

    return 0;
}

我曾猜测,我们不需要在展开式中使用超过10个项就可以达到所需的精度,因此内部for循环是我们循环范围[0,10]内n的值的地方。
另外,我们有几条线专门用来检查我们是否达到了要求的精度。首先计算出当前评估与之前评估之间的绝对差值,并取绝对差值。检查差异是否小于我们的ε值(1E-3)是提前退出循环的标准。我还需要检查当前值和以前值的符号是否相同,因为在计算e(-1)的值时出现了一些波动,这就是条件中的第一个子句所做的。
float evalSum(int start, int end, int val, term fnct)
{
    float sum = 0;
    for(int n = start; n <= end; n++)
    {
        sum += fnct(n, val);
    }

   return sum;
}

这是一个实用函数,我编写它来计算一个系列的前n项。start是起始值(此代码始终为0),而end是结束值。最后一个参数是指向函数的指针,该函数表示如何计算给定项。在这段代码中,fnct可以是指向任何接受整数参数并返回浮点值的函数的指针。
float expTerm(int n, int x)
{
    return (float)mypow(x,n)/(float)fact(n);
}

隐藏在这一行函数中的是大部分工作发生的地方。此函数表示e(n)的泰勒展开式的闭合形式。仔细看上面,您应该可以看到我们正在计算$\fract{x^n}{n!}$表示x和n的给定值。作为提示,对于余弦部分,需要创建一个函数来计算cos的泰勒展开式中某个项的闭式。这是由$(-1)^n\fact{x^{2n}{(2n)给出的!}$.
int fact(int n)
{
    if(0 == n)
        return 1;             // by defination
    else if(1 == n)
        return 1;
    else
        return n*fact(n-1);
}

这只是阶乘函数的标准实现。这里没什么特别的。
int mypow(int base, int exp)
{
    int result = 1;

    while(exp)
    {
        if(exp&1)              // b&1 quick check for odd power
        {
            result *= base;
        }

        exp >>=1;              // exp >>= 1 quick division by 2
        base *= base;
    }

    return result;
}

做指数运算的自定义函数。我们当然可以使用<math.h>中的版本,但是因为我知道我们只会使用整数幂,所以我们可以编写一个优化的版本。提示:在做余弦运算时,您可能需要使用<math.h>中的版本来处理浮点基。
bool sgn(float x)
{
    if(x < 0) return false;
    else return true;
}

一个非常简单的函数来确定浮点值的符号,否则返回true是正的,否则返回false。
这段代码是在我的Ubuntu-14.04上使用gcc版本4.8.4编译的:
******@crossbow:~/personal/projects$ gcc -std=c99 -pedantic -Wall series.c -o series
******@crossbow:~/personal/projects$ ./series
the approximate value of exp(-2) is 0.135097
the approximate value of exp(-1) is 0.367857
the approximate value of exp(0) is 1.000000
the approximate value of exp(1) is 2.718254
the approximate value of exp(2) is 7.388713

使用bc给出的预期值为:
******@crossbow:~$ bc -l
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
e(-2)
.13533528323661269189
e(-1)
.36787944117144232159
e(0)
1.00000000000000000000
e(1)
2.71828182845904523536
e(2)
7.38905609893065022723

如您所见,这些值完全在您所要求的公差范围内。我把它作为练习来做余弦部分。
希望能帮上忙,
-T型

关于c - 泰勒级数,错误最多10 ^ -3,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34192937/

10-09 06:38