gpt4 book ai didi

c - 使用 Horner 方法求多项式导数的函数错误在哪里?

转载 作者:太空宇宙 更新时间:2023-11-03 23:39:44 25 4
gpt4 key购买 nike

我使用 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

如您所见,霍纳的方法可以很好地计算多项式,但不能正确计算导数。无论我使用教授给我的列表中的系数示例是什么,这始终是相同的错误。

最佳答案

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

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

关于c - 使用 Horner 方法求多项式导数的函数错误在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49144369/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com