I prefer this :)
#include <utility>
#include <limits>
#include <iostream>
#include <cmath>
static const double bad_double = std::numeric_limits<double>::quiet_NaN();
class QuadSolver
{
static bool IsZero(double val)
{
return (val == 0) || (fabs(val) < std::numeric_limits<double>::epsilon());
}
enum {state_unknown, state_invalid, state_no_solution, state_single_solution, state_equal_solutions, state_double_solution} state;
std::pair<double, double> solution;
double a, b, c;
public:
QuadSolver(double a_, double b_, double c_) : a(a_), b(b_), c(c_), state(state_unknown), solution(bad_double, bad_double)
{
if (IsZero(a))
if(IsZero(b))
state = state_invalid;
else
{
state = state_single_solution;
solution.first = -c / b;
}
else
{
double disc = b * b - 4 * a * c;
if (IsZero(disc))
{
state = state_equal_solutions;
solution.first = solution.second = -b / (2 * a);
}
else if (disc > 0)
{
state = state_double_solution;
const int sign = (b == fabs(b) ? 1 : -1);
const double q = -(b + sign * sqrt(disc)) / 2;
solution = std::make_pair(q / a, c / q);
}
else
state = state_no_solution;
}
}
std::ostream& Out(std::ostream& out) const
{
if (state == state_unknown)
return out;
out << "Equation " << a << "*x*x + "<< b << "*x + " << c << " = 0";
switch (state)
{
case state_invalid:
out << " is ill formed";
break;
case state_no_solution:
out << " has no solution";
break;
case state_single_solution:
out << " has a single solution: x = " << solution.first;
break;
case state_equal_solutions:
out << " has two equal solutions: x1 = x2 = " << solution.first;
break;
case state_double_solution:
out << " has two solutions: x1 = " << solution.first << " and x2 = " << solution.second;
break;
}
return out << '.' << std::endl;
}
};
inline std::ostream& operator << (std::ostream& out, const QuadSolver& qs)
{
return qs.Out(out);
}
Test program showing usage:
int main(void)
{
std::cout << "Quadratic equation a*x*x + b*x + c = 0" << std::endl;
while (std::cin.good())
{
double a, b, c; std::cout << "Enter a b c (q to quit)";
std::cin >> a >> b >> c;
if (std::cin.good())
std::cout << QuadSolver(a, b, c);
}
return 0;
}
cheer,
AR
Edited to address Federico's objection and (slightly) improve the code.