首页 > 解决方案 > 当系数可能为 0 时求解二次方程

问题描述

我被要求编写一个 C 程序来解决方程ax 2 +bx+c=0,其中abcdouble是具有类型的系数。任何系数都可以为零。在这个问题中,我不清楚如何处理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;
}

标签: cfloating-pointdouble

解决方案


由于不允许除以零,您必须将问题分为 4 种情况:

  1. a != 0:这是您在代码中处理的情况。

  2. a == 0 && b != 0 :这是一个线性方程,解为 x = -c/b

  3. a == 0 && b == 0 && c != 0 :x 没有可能的值。

  4. 在最后一种情况下,a、b 和 c 等于 0:x 有无穷多个解。

编辑:删除与 epsilon 的比较,因为它们似乎没用


推荐阅读