我使用二元插值求值
a
和b
(与a < b
)之间的多项式根,但输出总是0.00
,我真的无法解决。
下面是我的C代码:
#include <stdio.h>
#include <math.h>
float fx(int a3, int a2, int a1, int a0, float x) {
return a3 * pow(x, 3) + a2 * pow(x, 2) + a1 * x + a0;
}
float binary(int a3, int a2, int a1, int a0, float a, float b, float *result)
{
float fa = fx(a3, a2, a1, a0, a), fb = fx(a3, a2, a1, a0, b);
float mid = (a + b) / 2;
float fmid = fx(a3, a2, a1, a0, mid);
float root = 0.0;
if (b - a >= 0.001) {
if (fa * fb >= 0) {
*result = 0;
return 0;
}
if (fa * fb < 0)//
{
if (fmid == 0) {
*result = mid;
return 0;
}
else if (fmid * fa > 0) {
a = mid;
root = binary(a3, a2, a1, a0, a, b, result);
}
else if (fmid * fb > 0) {
b = mid;
root = binary(a3, a2, a1, a0, a, b, result);
}
}
}
*result = mid;
return 0;
}
int main()
{
int a3, a2, a1, a0;
float a, b, result;
scanf("%d %d %d %d", &a3, &a2, &a1, &a0);
scanf("%f %f", &a, &b);
float output = binary(a3, a2, a1, a0, a, b, &result);
printf("%.2lf", output);
return 0;
}
我相信在使用
binary
函数时,我使用了递归。虽然我通过递归成功找到了结果,但它没有返回正确的值。在 VSCode 中使用调试器时,我观察到找到的最终值是正确的,但该函数没有返回预期结果。我的测试数据包括a3 = 3, a2 = -1, a1 = -3, a0 = 1
。预期输出是0.33
,但实际输出是0.00
。
请帮助我!我只是一年级的学生,我花了一晚上的时间才解决这个问题!!!
binary()
在所有情况下都会返回 0
,这是您分配给 output
变量的值,即您打印的内容。您可以 return
结果并消除 result
参数、result
和 root
变量:
#include <math.h>
#include <stdio.h>
double fx(int a3, int a2, int a1, int a0, double x) {
return a3 * pow(x, 3) + a2 * pow(x, 2) + a1 * x + a0;
}
double binary(int a3, int a2, int a1, int a0, double a, double b) {
double fa = fx(a3, a2, a1, a0, a);
double fb = fx(a3, a2, a1, a0, b);
double mid = (a + b)/2;
double fmid = fx(a3, a2, a1, a0, mid);
if (b - a >= 0.001) {
if (fa * fb >= 0)
return 0;
if (!fmid)
return mid;
if(fmid * fa > 0)
return binary(a3, a2, a1, a0, mid, b);
if(fmid * fb > 0)
return binary(a3, a2, a1, a0, a, mid);
}
return mid;
}
int main(void) {
int a3, a2, a1, a0;
double a, b;
scanf("%d %d %d %d", &a3, &a2, &a1, &a0);
scanf("%lf %lf", &a, &b);
printf("%.2lf", binary(a3, a2, a1, a0, a, b));
}
您还没有为完整的测试用例提供
a
和b
,所以我不知道它是否返回0.33
的预期结果。尽管如此,这确实回答了你为什么它总是返回的问题0
。
存在多个问题:
函数
binary
始终返回0
。返回值不是存储在*result
中的根值,它应该是成功的指示符:例如:如果fx(a)
和fx(b)
具有相同的符号,则函数失败。
你应该返回递归调用的结果,而不是将其存储到
root
中然后忘记它,最后将mid
的初始值存储到*result
中。
不建议使用具有潜在负值的
pow
。请改用嵌套乘法。
有多个冗余测试。
您应该测试
scanf()
是否无法转换预期的输入值。
这是修改后的版本:
#include <stdio.h>
#include <math.h>
float fx(int a3, int a2, int a1, int a0, float x) {
return ((a3 * x + a2) * x + a1) * x + a0;
}
int binary(int a3, int a2, int a1, int a0, float a, float b, float *result) {
float fa = fx(a3, a2, a1, a0, a);
float fb = fx(a3, a2, a1, a0, b);
float mid = (a + b) / 2;
float fmid = fx(a3, a2, a1, a0, mid);
if (fa == 0) {
*result = a;
return 1;
}
if (fb == 0) {
*result = b;
return 1;
}
if (fmid == 0 || fabs(b - a) < 0.001) {
*result = mid;
return 1;
}
if (fa * fb > 0) {
// failure: function has the sign sign on boundaries
*result = mid;
return 0;
}
if (fmid * fa > 0) {
// interpolate between mid and b
return binary(a3, a2, a1, a0, mid, b, result);
} else {
// interpolate between a and mid
return binary(a3, a2, a1, a0, a, mid, result);
}
}
int main() {
int a3, a2, a1, a0;
float a, b, result;
if (scanf("%d %d %d %d", &a3, &a2, &a1, &a0) != 4)
return 1;
if (scanf("%f %f", &a, &b) != 2)
return 1;
int success = binary(a3, a2, a1, a0, a, b, &result);
printf("success=%d, result=%.2f\n", success, result);
return 0;
}
请注意,上述实现会在每个递归步骤重新计算边界值,而使用循环并仅计算中点处的值会更有效。测试
fabs(b - a) < 0.001
是有问题的,但与使用 %.2f
输出的精度一致。
这是一个非递归实现:
int binary(int a3, int a2, int a1, int a0, float a, float b, float *result) {
float fa = fx(a3, a2, a1, a0, a);
float fb = fx(a3, a2, a1, a0, b);
if (fa == 0) {
*result = a;
return 1;
}
if (fb == 0) {
*result = b;
return 1;
}
if (fa * fb >= 0) {
// failure: function has the sign sign on boundaries
*result = 0;
return 0;
}
for (;;) {
float mid = (a + b) / 2;
float fmid = fx(a3, a2, a1, a0, mid);
if (fmid == 0 || fabs(b - a) < 0.001) {
*result = mid;
return 1;
}
if (fa * fmid > 0) {
// interpolate between mid and b
a = mid;
fa = fmid;
} else {
// interpolate between a and mid
b = mid;
fb = fmid;
}
}
}