求多项式根的二进制插值总是输出 0.00

问题描述 投票:0回答:2

我使用二元插值求值

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

请帮助我!我只是一年级的学生,我花了一晚上的时间才解决这个问题!!!

c polynomials
2个回答
0
投票

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


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;
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.