首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Horner方法计算多项式导数的误差在哪里?

用Horner方法计算多项式导数的误差在哪里?
EN

Stack Overflow用户
提问于 2018-03-07 12:50:56
回答 1查看 440关注 0票数 2

我使用horners方法来创建代码,该代码可以计算多项式,以及它对任何给定系数集的导数。当我对值进行硬编码时,horner的方法工作得很好,但当我更改代码以从命令行提示符获取任何输入时,horner的导数开始打印出带有几十个零的疯狂数字。但霍纳的多项式方法仍在正确计算中。我不确切地知道这段代码中的错误在哪里。

代码语言:javascript
复制
    #include<stdio.h>
    #include<math.h>
    #include<stdlib.h>

  double horner(double *coeffs, int s, double x)
{
  int i;
  double res = 0.0;

  for(i=s-1; i >= 0; i--)
  {
    res = res * x + coeffs[i];
  }
  return res;
}

double hornerDerivative(double *coeffs, int s_1, double x_1)
{
  int i_1;
  double res_1 = 0.0;

  for(i_1 = s_1; i_1 >= 1; i_1--)
  {
    res_1 = res_1 * x_1 + i_1*coeffs[i_1];
  }
  return res_1;
}

double newton(double *coeffs, double a, double b, double eps)
{
       int N = 0;
       double c = ((a+b)/2);

       while(N < 10)
       {
               double y = horner(coeffs, sizeof(coeffs), c);
               double y_derivative = hornerDerivative(coeffs, sizeof(coeffs), c);
               double c_1 = c - (y/y_derivative);
               printf("c: %f\t",c);
               printf("y: %f\t",y);
               printf("y_der: %f\t",y_derivative);
               printf("c_1: %f\n",c_1);
               if(fabs(c_1-c)<eps)
               {
                    return c_1;                   
               }
               c = c_1;
               N = N + 1;
       }
}

int main(int argc, char **argv)
{
  printf("# of arguments%d\n\n\n\n", argc);
  double coeffs[argc-3];

  double a = atof(argv[argc-2]);
  double b = atof(argv[argc-1]);
  double eps = .001;

  int i;
  for(i=1; i < argc-2; i++)
  {
           coeffs[i-1] = atof(argv[argc-2-i]);
  }

  printf("The root of the equation is: %f\n", newton(coeffs, a, b, eps));
  system("pause");
  return 0;
}

这是我得到的输出。

代码语言:javascript
复制
C:\Dev-Cpp>ProgrammingAssignment1.exe 1 -6 4 12 1 4
# of arguments7



c: 2.500000     y: 0.125000     y_der: 61390858609268995000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000     c_1: 2.500000
The root of the equation is: 2.500000

如你所见,horner的方法计算多项式很好,但它没有正确地计算导数。无论我对教授给我的列表中的系数使用什么示例,这都是相同的错误。

EN

回答 1

Stack Overflow用户

发布于 2018-03-07 17:02:48

如上所述,您的代码中存在一些问题:

sizeof

  • 使用率。

代码语言:javascript
复制
- `sizeof <array>` will return the size of  **in bytes**.
- `sizeof <pointer>` will return the size of a pointer on your system typically 4 (32 bits arch) or 8 (64 bits arch).

看看这段代码:

void foo(int * p) { printf("sizeof指针为%z\n",sizeof p);} void bar() { int a256;printf("sizeof数组为%z\n",sizeof a);foo(a);}

它将打印:

sizeof数组是1024,sizeof指针是8

所以你不能使用sizeof(coeffs)

当牛顿的方法需要超过10步才能收敛时,你会怎么处理?

  • ?如果从未满足条件fabs(c_1-c)<eps,则应返回一些值(为什么不返回一些警告?)

一种解决方案可能是:

代码语言:javascript
复制
#include<stdio.h>
#include<math.h>
#include<stdlib.h>

double horner(double *coeffs, int s, double x)
{
    int i;
    double res = 0.0;

    for(i=s-1; i >= 0; i--)
    {
        res = res * x + coeffs[i];
    }
    return res;
}

double hornerDerivative(double *coeffs, int s_1, double x_1)
{
    int i_1;
    double res_1 = 0.0;

    for(i_1 = s_1; i_1 >= 1; i_1--)
    {
        res_1 = res_1 * x_1 + i_1*coeffs[i_1];
    }
    return res_1;
}

/* New parameter here: cnt the number of elements in coeffs */
double newton(double *coeffs, size_t cnt, double a, double b, double eps)
{
   int N = 0;
   double c = ((a+b)/2);

   while(N < 10)
   {
        /* replacing sizeof... by cnt */
        double y = horner(coeffs, cnt, c);
        /* replacing sizeof... by cnt */
        double y_derivative = hornerDerivative(coeffs, cnt, c);
        double c_1 = c - (y/y_derivative);
        printf("c: %f\t",c);
        printf("y: %f\t",y);
        printf("y_der: %f\t",y_derivative);
        printf("c_1: %f\n",c_1);
        if(fabs(c_1-c)<eps)
        {
            return c_1;                   
        }
        c = c_1;
        N = N + 1;
   }

   /* always return some value */
   fprintf(stderr, "Warning newton do not converge in 10 steps...\n")
   return c;
}

int main(int argc, char **argv)
{
    printf("# of arguments%d\n\n\n\n", argc);
    double coeffs[argc-3];

    double a = atof(argv[argc-2]);
    double b = atof(argv[argc-1]);
    double eps = .001;

    int i;
    for(i=1; i < argc-2; i++)
    {
        coeffs[i-1] = atof(argv[argc-2-i]);
    }

    /* pass the number of elements in coeffs array */
    printf("The root of the equation is: %f\n", newton(coeffs, argc-3, a, b, eps));    
    return 0;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49144369

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档