我使用horners方法来创建代码,该代码可以计算多项式,以及它对任何给定系数集的导数。当我对值进行硬编码时,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的方法计算多项式很好,但它没有正确地计算导数。无论我对教授给我的列表中的系数使用什么示例,这都是相同的错误。
发布于 2018-03-07 17:02:48
如上所述,您的代码中存在一些问题:
sizeof的
- `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,则应返回一些值(为什么不返回一些警告?)一种解决方案可能是:
#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;
}https://stackoverflow.com/questions/49144369
复制相似问题