繁体   English   中英

使用霍纳方法对多项式求导的函数中的错误在哪里?

[英]Where is the error in my function for derivative of polynomial using Horner's method?

我正在使用 horners 方法来创建可以计算多项式的代码,以及我给定的任何一组系数的导数。 当我对值进行硬编码时,Horner 的方法运行良好,但是当我更改我的代码以从命令行提示符接收任何输入时,horner 的衍生方法开始打印出带有数十个零的疯狂数字。 但是 horner 的多项式方法仍在正确计算。 我不完全知道此代码中的错误在哪里。

    #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;
}

这是我得到的输出。

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 的方法可以很好地计算多项式,但没有正确计算导数。 无论我对教授给我的列表中的系数使用什么示例,这始终是相同的错误。

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

  • sizeof用法。

    • sizeof <array>将返回以字节单位的大小。
    • sizeof <pointer>将返回系统上指针的大小,通常为 4(32 位结构)或 8(64 位结构)。

    看看这段代码:

     void foo(int * p) { printf("sizeof pointer is %z\\n", sizeof p); } void bar() { int a[256]; printf("sizeof array is %z\\n", sizeof a); foo(a); }

    它会打印:

     sizeof array is 1024 sizeof pointer is 8

    所以你不能使用sizeof(coeffs)

  • 当牛顿法超过10步收敛时,你如何处理? 如果条件fabs(c_1-c)<eps从未满足,您应该返回一些值(为什么不发出一些警告?)


一种解决方案可能是:

#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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM