gpt4 book ai didi

c - 求解系数可能为0的二次方程

转载 作者:太空宇宙 更新时间:2023-11-04 01:18:05 25 4
gpt4 key购买 nike

我被要求编写一个 C 程序来求解方程 ax2+bx+c=0,其中 a , bcdouble 类型的系数。任何系数都可以为零。在这个问题中,我不清楚如何处理 double 变量。

这是我的代码。至于现在,我知道我的程序无法区分两个根和无限多个根。它也没有检测到“线性方程情况”。我怎样才能让它检测到无限多的解决方案?评论中还建议我在判别式前用负号计算根,如果 b > 0,然后使用 Viet 定理。我明白这是因为将两个数字相加总是更准确。我也想我应该对 b < 0 做完全相反的事情。但是如果 b == 0 呢?在这种情况下,程序不会做任何事情。或者我应该只在 b < 0 中包含 b == 0 并让 b <= 0 ?

#include <stdio.h>
#include <math.h>
#include <float.h>

int main() {
double a, b, c, x1, x2;

scanf("%lf", &a);
scanf("%lf", &b);
scanf("%lf", &c); // just reading variables
//ax^2+bx+c=0
if ((b * b - 4 * a * c) < 0) {
printf("no");
} else {
x1 = (-b + sqrt(b * b - 4 * a * c)) / (2 * a); //calculating roots
x2 = (-b - sqrt(b * b - 4 * a * c)) / (2 * a);
if ((fabs((a * x1 * x1 + b * x1 + c)) < DBL_EPSILON) & (fabs((a * x2 * x2 + b * x2 + c)) < DBL_EPSILON)) { //plugging the roots in
if (fabs((x1 - x2)) < DBL_EPSILON) { //checking if the roots are equal
printf("%lf", &x1); // if they are equal, we print only one of them
} else {
printf("%lf", &x1); // if they are not equal, we print both.
printf("\n %lf", &x2);
}
} else { // if there are no two valid roots
if ((fabs((a * x1 * x1 + b * x1 + c)) < DBL_EPSILON)) // we try to find one root.
printf("%lf", &x1);
if (fabs((a * x2 * x2 + b * x2 + c)) < DBL_EPSILON)
printf("%lf", &x2);
if ((fabs((a * x1 * x1 + b * x1 + c)) > DBL_EPSILON) & (fabs((a * x2 * x2 + b * x2 + c)) > DBL_EPSILON)) // if both of the plugged roots don't satisfy the equation
printf("no");
}
}
return 0;
}

最佳答案

求解系数可能为0的二次方程

How can I make it detect an infinite number of solutions?

a==0 && b == 0 && c == 0时。
这段代码中的任何地方都不需要 DBL_EPSILON。另见 @Eric Postpischil .

But what if b == 0 ?

if (b == 0) {  // y = a*x*x + c
if (a) {
double dd = -c/a;
if (dd >= 0) {
double d = sqrt(d);
printf_roots("+/- roots", d,-d);
} else {
printf_roots("Complex roots", NAN, NAN); // Note NAN may not exist
}
} else if (c) { // y = 0*x*x + c, c != 0
printf_roots("No roots", NAN, NAN);
} else { // y = 0*x + 0
printf_roots("Infinite roots", -HUGE_VAL, HUGE_VAL);
}

Or should I just include b == 0 in b < 0 and have b <= 0 ?

除非编码目标需要在 b==0 时进行特殊输出,否则我只会在 b==0 上将 vector 代码作为 a= =0 发生。

if (a==0) {
if (b == 0) {

与许多 FP 代码一样,二次方程很容易溢出并达到 0,这两种情况都会失去所有精度。

考虑下面的代码:不必要的减法可能会导致溢出或截断为 0,而第二个可能不会。它取决于许多因素。

if ((b * b - 4 * a * c) < 0)
//
if (b * b < 4 * a * c)

此外,C 允许使用更广泛的数学进行各种计算。研究FLT_EVAL_METHOD .因此,为防止 sqrt(value_less_than_0),代码应计算 discriminate然后测试将应用于 sqrt(x) 的对象 x

//if ((b * b - 4 * a * c) < 0) {
// printf("no");
//} else {
// x1 = (-b + sqrt(b * b - 4 * a * c))

double discriminate = b * b - 4 * a * c;
if (discriminate < 0) {
printf("no");
} else {
double d = sqrt(discriminate);
x1 = (-b + d)

关于“如果 b > 0,则用判别式前的负数计算根,然后使用 Viet 定理”的想法,我建议使用下面的方法来提高保留精度,它不会像带符号的值一样减去。

    double d = sqrt(discriminate);

// Note x1*x2 = c/a
if (b < 0) {
x2 = (-b + d)/(2*a);
x1 = c/a/x2;
} else {
x1 = (-b - d)/(2*a);
x2 = c/a/x1;
}
printf_roots("2 roots", x1, x2);

关于 printf("%lf", &x1); 的注释。您没有在启用所有警告的情况下进行编译。节省时间 - 启用它们。应该是 printf("%lf", x1); 没有 &

进一步double float 。对于 FP 代码开发,使用 "%e""%a""%g" 来完整查看重要信息。

printf("%g\n", some_double);
// or better
printf("%.*e\n", DBL_DECIMAL_DIG -1, some_double);

关于c - 求解系数可能为0的二次方程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52174394/

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