我正在研究一个程序,该程序应该计算二次函数的根并输出它的根。但是,输出并不是所有情况下的输出。当它应该没有解决方案或是微不足道时,它输出为-nan(ind)
。当它应该有一个解决方案时,它会输出x1 = -nan(ind)
和x2 = -inf
。我不太确定为什么会这样,我真的可以使用一些帮助。这是我的代码:
#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
答案 0 :(得分:0)
问题是你在这里除以0:
imaginaryNum = (sqrt(-d)) / (2 * a);
浮点数的行为由IEEE-754标准定义。它声明如果您将数字除以0,则数字将表示为无穷大。此外,在C ++中除以零是undefined behaviour。
这就是您要检查用户输入的原因。您可能无法输入无效数字,但用户可以很好地输入。此代码将是一个临时解决方法。请注意,这只是您问题的临时解决方案,因为仍然会接受“12a”之类的字符串:
#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.
}
答案 1 :(得分:0)
首先,如果a很小,我们可以说平方项消失了。所以它变成了一根直线(除非与x轴平行)。
然后,如果行列式为负,则等式不会越过x轴。所以没有根,或者,如果你愿意,根是虚构的。
要提高数值稳定性,请使用此功能。这是为了避免接近0/0的术语,这可能会使用高中学校公式。
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;
}
答案 2 :(得分:0)
以下是代码中存在问题的部分:
// 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 behavior。另外正如 ScY :
所指出的那样浮点数的行为由IEEE-754 Standard定义。它指出 如果您将数字除以0,则数字将表示为 无穷大。
我的建议是检查 a 是否等于零。如果 a 等于零,则抛出错误。
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()函数实际上并不是可重用的,因此它应该保持简短。