执行被困在C程序中

时间:2017-09-09 01:24:25

标签: c function precision

我正在研究C中的一个简单问题,设计一个二次方程求解程序,但由于某种原因,我无法使其工作。我已经尝试完成每个部分并将它们拉入自己的程序来测试它们的执行,并且它们似乎单独工作,但是当我执行程序时,它会被卡住。任何帮助表示赞赏!

//A program to solve a quadratic equation
#include <stdio.h>

float absoluteValue (float x)
{
        if (x < 0)
        x = -x;
        return (x);
}

float squareRoot (float x)
{
        const float epsilon = .00001;
        float guess = 1.0;

        while (absoluteValue (guess * guess - x) >= epsilon )
                guess = (x / guess + guess) / 2.0;
                return guess;
}

float quadraticEquation (float a, float b, float c)
{
         float rootOne, rootTwo;

        if ((b * b - 4 * a * c) <= 0) {
                printf ("The roots are imaginary.");
        }
        else {
                rootOne = (-b + squareRoot(b * b - 4 * a * c)) / (2 * a);
                rootTwo = (-b - squareRoot(b * b - 4 * a * c)) / (2 * a);
        }

        return 0;

}

int main (void)
{
        float a, b, c;
        a = 10;
        b = 30;
        c = 5;

//      printf ("Please enter a value fo A, B, and C: \n");
//      scanf ("%f%f%f", &a, &b, &c);
        quadraticEquation(a, b, c);

        return 0;
}

1 个答案:

答案 0 :(得分:3)

当你有一个程序陷入循环时,找出它发生的位置的最好方法是在调试器中运行你的程序,让它卡住,然后暂停调试器。在GDB或LLDB中,这可以通过键入Control-C来完成,但在其他调试器中,UI可能不同(在基于GUI的IDE中,可能会有一个可以单击的按钮);但是,每个调试器都应该有一个暂停功能。这将使调试器准确显示执行处于卡住位置的位置,从而可以快速确定问题所在。

无论如何,在这种情况下,导致无限循环的行是:

while (absoluteValue (guess * guess - x) >= epsilon )
    guess = (x / guess + guess) / 2.0;

通过逐步调试并使用调试器来分析变量的内容,在它被卡住的位置执行:

x是700。

guess是26.4575119,距离700的平方根不远。

guess * guess - x是-0.0000610351563,其绝对值大于epsilon,即0.00001。

然后将

guess设置为(x / guess + guess) / 2.0的值,该值出现在26.4575119。不幸的是,这与guess已经存在的值相同,因此循环将永远持续。

基本上,浮点不精确会导致你的结果永远不会超出正确答案的epsilon。您可以调整算法来解决此问题,但除非这是针对某些要求您不使用除stdio之外的任何内容的任务,我建议您查看math.h,其中包含sqrt将为你计算平方根的函数,而不是自己重新发明轮子。