首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++:如何确定二次函数的解是否平凡或不存在?

C++:如何确定二次函数的解是否平凡或不存在?
EN

Stack Overflow用户
提问于 2017-02-06 17:05:24
回答 3查看 185关注 0票数 0

我正在编写一个程序,它可以计算一个二次函数的根,并输出它的根。然而,并不是所有情况下的输出都是应该的。当它被认为没有解决方案或微不足道时,它输出为-nan(ind)。当它应该有一个解决方案时,它输出x1 = -nan(ind)x2 = -inf。我不太确定为什么会发生这种情况,我真的需要一些帮助。下面是我的代码:

代码语言:javascript
复制
#include <iostream>
#include <cmath>
#include <iomanip>

using namespace std;

int main() {

    // Initialize and define the variables:
    // a = the variable that stores the value for 'a' in the quadratic
    // b = the variable that stores the value for 'b' in the quadratic
    // c = the variable that stores the value for 'c' in the quadratic
    // d = the variable that stores the determinant of the quadratic function to find the nature of the roots (b^2-4ac)
    // root1 = the variable that stores the first possible root of a quadratic function
    // root2 = the variable that stores the second possible root of a quadratic function
    // realNum = the variable that stores the real portion of the complex roots
    // imaginaryNum = the variable that stores the imaginary portion of the complex roots
    double a, b, c, d, root1, root2, realNum, imaginaryNum;

    // Ask the user to input a value for variable 'a' of the quadratic
    // NOTE: 'setprecision' specifies the minimum precision, 'fixed' states a fixed number of decimals will
    // appear after the entered digit
    cout << "Please input a: " << setprecision(4) << fixed;
    cin >> a;                                   /// Store the value in variable 'a'

    // Ask the user to input a value for variable 'b' of the quadratic
    // NOTE: 'setprecision' specifies the minimum precision, 'fixed' states a fixed number of decimals will
    // appear after the entered digit
    cout << "Please input b: " << setprecision(4) << fixed;;
    cin >> b;                                   /// Store the value in variable 'b'

    // Ask the user to input a value for variable 'c' of the quadratic
    // NOTE: 'setprecision' specifies the minimum precision, 'fixed' states a fixed number of decimals will
    // appear after the entered digit
    cout << "Please input c: " << setprecision(4) << fixed;;
    cin >> c;                                   /// Store the value in variable 'c'

    // Calculate the determinant of the quadratic (b^2 - 2ac)
    d = ((pow(b, 2.0)) - (4 * a * c));


    // Check to see if the determinant is greater than 0
    if (d >= 0) {

        // Calculate each of the two possible roots for the quadratic
        root1 = (-b + sqrt(d)) / (2 * a);
        root2 = (-b - sqrt(d)) / (2 * a);

        // Display to the user that a solution does exist for the following quadratic
        cout << "Your equation has real roots: " << root1 << " and " << root2 << "." << endl;

    }


    // Check to see if the determinant is greater than 0
    else if (d < 0) {

        // Calculate the real portion of the complex roots for the quadratic
        realNum = (-b) / (2 * a);

        // Calculate the imaginary portion of the complex roots for the quadratic
        imaginaryNum = (sqrt(-d)) / (2 * a);

        // Combine the two portions of the complex roots and display the calculated complex roots to the user
        cout << "Your equation has complex roots: " << realNum << " + " << imaginaryNum << "i and "
        << realNum << " - " << imaginaryNum << "i." << endl;

    }

    // Indicate that the program ended successfully
    return 0;

} // End of function main
EN

回答 3

Stack Overflow用户

发布于 2017-02-06 18:02:18

问题是你在这里除以0:

代码语言:javascript
复制
 imaginaryNum = (sqrt(-d)) / (2 * a);  

浮点数的行为由IEEE-754标准定义。它指出,如果将一个数字除以0,则该数字将表示为infinity。此外,在C++中,除以零是undefined behaviour

这就是你想要检查用户输入的原因。您可能不会输入无效的数字,但用户可以很好地输入。此代码将是一种临时解决方法。请注意,这只是您的问题的临时解决方案,因为像"12a“这样的字符串仍将被接受:

代码语言:javascript
复制
#include <iostream>
#include <exception>

int main() {
    double input;
    bool is_valid = false;
    while (is_valid != true) {
        try {
            cin >> input; //
            if (!cin) {
                cin.clear(); // reset failbit
                cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
                throw std::bad_exception();
            }
            else {
                is_valid = true;
            }
        }
        catch (...) {
            std::cout << "Input a number!\n";
        }
    }
    // ... Do this for all your inputs and proceed.
}
票数 0
EN

Stack Overflow用户

发布于 2017-02-06 18:54:19

首先,如果a很小,我们可以说平方项消失了。所以它变成了一条有一个根的直线(除非平行于x轴)。

如果行列式是负数,则方程不会穿过x轴。所以没有根,或者,如果你喜欢,根是虚构的。

要提高数值稳定性,请使用此函数。它是为了避免使用高中公式可能突然出现的接近0/0的学期而编写的。

代码语言:javascript
复制
int quadratic_roots(double a, double b, double c, double *out)
{
    double rootb2minus4ac;
    double b2minus4ac;

    if(fabs(a) < FLT_EPSILON * 0.01)
    {
        if(fabs(b) > FLT_EPSILON * 0.01)
        {
            out[0] = c/-b;
            return 1;
        }
        return 0;
    }

    b2minus4ac = b*b - 4*a*c;
    if(b2minus4ac > 0)
    {
        rootb2minus4ac = sqrt(b*b - 4*a*c);
        if(b >= 0)
        {
            out[0] = (-b -rootb2minus4ac)/(2*a);
            out[1] = (2*c)/ (-b -rootb2minus4ac);
        }
        else
        {
            out[0] = (2*c)/(-b + rootb2minus4ac);
            out[1] = (-b + rootb2minus4ac)/(2*a);
        }
        if(a < 0)
        {
            double temp = out[0];
            out[0] = out[1];
            out[1] = temp;
        }
        return 2;
    }
    else if(b2minus4ac == 0.0)
    {
        out[0] = (2*c)/-b;
        return 1;
    }
    return 0;
}
票数 0
EN

Stack Overflow用户

发布于 2017-02-06 23:14:38

以下是代码中有问题的部分:

代码语言:javascript
复制
// Calculate each of the two possible roots for the quadratic
        root1 = (-b + sqrt(d)) / (2 * a);
        root2 = (-b - sqrt(d)) / (2 * a);
        //....
        // Calculate the real portion of the complex roots for the quadratic
        realNum = (-b) / (2 * a);

        // Calculate the imaginary portion of the complex roots for the quadratic
        imaginaryNum = (sqrt(-d)) / (2 * a);

可以清楚地看到,变量a在分母中。变量a可以包含任何值,包括零。除以零,可以得到C++中的Undefined behaviorScY也指出了这一点

浮点数的行为由IEEE-754 Standard定义。它指出,如果将一个数字除以0,则该数字将表示为无穷大。

我的建议是检查a是否等于0。如果a等于0,则抛出错误。

代码语言:javascript
复制
cout << "Please input a: " << setprecision(4) << fixed;
cin >> a;     
if (a == 0){
   std::cerr << "The variable a should not be equal with 0";
   return 1;
}

我强烈建议你,创建一个函数来计算任何给定多项式的根。这可以使您的代码更具可读性和效率。此外,main()函数实际上并不是可重用的,所以应该保持简短。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42063887

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档