[英]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.