实现maclaurin系列,但得到错误的答案

时间:2018-12-24 21:07:18

标签: c arrays loops for-loop taylor-series

我正在尝试仅针对Mauriac系列实现系列中的前7个功能。我有一个数组,其中包含(0)的所有值,最多5个导数。但仅出于我的目标,我需要执行以下数学函数:

f(x)= 2 + 0-13x ^ 2 + 26 * x ^ 3 +(-299/12)*(x ^ 4)+ 13 * x ^ 5

所以如果:f(2)= 175.3

但是,代码却给了我f(2)= 275.0

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int x,i;

    double term [5] = {2,0,-13,26,-299,13};
    double answer;

    printf("\n\nEnter the value of x in the series :  ");
    scanf("%d",&x);

    term [2]*=(x*x);
    term [3]*=(x*x*x);
    term [4]*=(x*x*x*x)/12;
    term [5]*=(x*x*x*x*x);

    for (i=1; i <6; i++)
    {
        answer = answer + term[i];
    }

    printf("f(%d)= %lf",x,answer);

    return 0;
}

3 个答案:

答案 0 :(得分:1)

这里有几个问题。您似乎还不完全了解数组在C中的工作方式。声明term[5]是一个由5个元素组成的数组。该数组的第一个索引为term[0],因为数组始终从0开始。然后像这样继续进行。

  • term[0]
  • term[1]
  • term[2]
  • term[3]
  • term[4]

在声明term数组时,您正在尝试将6个值放入具有5个索引的数组中。这是行不通的,因此您必须执行term[6]来创建6个索引,而实际的6个索引超出范围。我注意到的另一件事是,在计算数组的每个元素时,您正在手动进行指数((x*x*x)等)。您应该真正使用pow() function from math.h。此函数来自C Math库。要编译包含C Math库的程序,必须将其指定给链接器。

与其像这样进行编译,

$ cc program.c -o program

您将像这样编译,以包含Math库。注意 -lm

$ cc program.c -lm -o program

我已经重构了您的程序以使用pow()函数。由于我们将x赋予了pow(),因此我也将其进行了翻倍,并将printf和scanf语句中的%d更改为正确的%f。正如其他人指出的那样,由于您使用的是未初始化的变量,因此我也给answer赋予了初始值0。

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

int main(void) {
    double x;
    int i;

    double term[6] = {2,0,-13,26,-299,13};
    double answer = 0;

    printf("\n\nEnter the value of x in the series :  ");
    scanf("%f",&x);

    term[2] *= pow(x, 2);
    term[3] *= pow(x, 3);
    term[4] *= pow(x, 4)/12;
    term[5] *= pow(x, 5);

    for (i = 0; i < 6; i++) {
        answer = answer + term[i];
    }

    printf("f(%f) = %f \n", x, answer);
    return 0;
}

我已经对此进行了测试,并在提示符下输入数字2产生了正确的f(2.00000) = 175.33333

答案 1 :(得分:0)

主要功能的另一个版本是:

  int main(void) {
    double x;
    int i;

    double term[6] = {2,0,-13,26,-299.0/12.0,13};
    double answer = 0;
    double p = 1;

    printf("\n\nEnter the value of x in the series :  ");
    scanf("%lf",&x);

    for (i = 0; i < 6; i++, p*=x) {
        answer = answer + term[i] * p;
    }

    printf("f(%f) = %f \n", x, answer);
    return 0;
  }

它删除x的多余乘法,并使术语的使用保持一致。视您的应用程序而定,可以将其改编为一个函数,该函数采用项数,项数组和x的值,然后返回答案。

答案 2 :(得分:0)

OP的目标是评估五次多项式

  

f(x)= 2-13x 2 + 26x 3 -(299/12)x 4 + 13x 5

但是发布的代码存在一些问题:

#include <stdio.h>

int main()
{
    int x,i;  // <- 'x' is declared as 'int'

    double term [5] = {2,0,-13,26,-299,13};  // <- this array has 6 elements, not 5
    double answer;
    // ...
    term [2]*=(x*x);
    term [3]*=(x*x*x);       //    Both 'x' and 12 are 'int', so an integer division
    term [4]*=(x*x*x*x)/12;  // <- is performed: 16/12 = 1 not 1.3333
    term [5]*=(x*x*x*x*x);   //    This is also inefficient

    for (i=1; i <6; i++)     // <- Given 'double term[5]', array indeces should be in [0, 5)
    {
        answer = answer + term[i];
    }
    // ...
}

一种更有效的评估多项式的​​方法是Horner's method,它“允许仅对n-1个乘法和n-1个加法进行次数为n的多项式的评估”。。 / p>

OP的多项式可以写为

  

f(x)= 2 + x(0 + x(-13 + x(26 + x(-299/12 + 13x))))

以下是此类实现的示例

#include <stdio.h>
#include <assert.h>

// Uses Horner's method to evaluate a polynomial
double evaluate_poly(double x, size_t n, double *coeffs)
{
    assert(n  &&  coeffs);
    double y = coeffs[--n];
    while (n)
    {
        y = coeffs[--n] + x * y;
    }
    return y;
}

int main(void)
{
    double terms[] = {
        2.0 , 0.0, -13.0, 26.0, -299.0/12.0, 13.0
    };
    size_t n_terms = sizeof terms / sizeof *terms;

    puts("  x         f(x)\n-----------------");
    for (int i = 0; i <= 10; ++i)
    {
        double x = i / 5.0;
        double answer = evaluate_poly(x, n_terms, terms);
        printf("%4.1lf   %10.6lf\n", x, answer);
    }

    return 0;
}

可测试的HERE