--------------------------------------------------------------------------------------------------------------- --------------
typedef double Number
int cesiummath::sign (number value) {
if (value > 0) {
return 1;
}
if (value < 0) {
return-1;
}
return 0;
}
--------------------------------------------------------------------------------------------------------------- ---------------
Class quadraticrealpolynomial{
Public
Static number Computediscriminant (number A, number B, number C);
Static std::vector<number>* computerealroots (number A, number B, number C, std::vector<number>& roots);
Private
Static number Addwithcancellationcheck (number left, number right, number tolerance);
Public
Number _root1;
Number _root2;
--------------------------------------------------------------------------------------------------------------- ---------------
Number Quadraticrealpolynomial::computediscriminant (number A, number B, number C)
{
Number discriminant = b * b-4.0 * a * C;
return discriminant;
}
std::vector<number>* quadraticrealpolynomial::computerealroots (number A, number B, number C, std::vector< number>& roots)
{
Number ROOT1, Root2;
Roots.clear ();
Number ratio;
if (a = = 0.0)
{
if (b = = 0.0)
{
Constant function:c = 0.
Return &roots;
}
Linear function:b * x + c = 0.
ROOT1 =-c/b;
Roots.push_back (ROOT1);
Return &roots;
}
else if (b = = 0.0)
{
if (c = = 0.0)
{
2nd order monomial:a * x^2 = 0.
ROOT1 = 0.0;
Root2 = 0.0;
Roots.push_back (ROOT1);
Roots.push_back (ROOT2);
Return &roots;
}
Number cmagnitude = Std::abs (c);
Number Amagnitude = Std::abs (a);
if ((Cmagnitude < Amagnitude) && (Cmagnitude/amagnitude < CESIUMMATH::_EPSILON14))
{
C ~= 0.0.
2nd order monomial:a * x^2 = 0.
ROOT1 = 0.0;
Root2 = 0.0;
Roots.push_back (ROOT1);
Roots.push_back (ROOT2);
Return &roots;
} else if ((Cmagnitude > Amagnitude) && (Amagnitude/cmagnitude < CESIUMMATH::_EPSILON14))
{
A ~= 0.0.
Constant function:c = 0.
Return &roots;
}
A * x^2 + c = 0
Ratio =-C/A;
if (ratio < 0.0)
{
Both roots is complex.
Return &roots;
}
Both roots is real.
Number root = std::sqrt (ratio);
ROOT1 =-root;
Root2 = root;
Roots.push_back (ROOT1);
Roots.push_back (ROOT2);
Return &roots;
}
else if (c = = 0.0)
{
A * x^2 + b * x = 0
Ratio =-b/a;
if (ratio < 0.0)
{
Root1 = ratio;
Root2 = 0.0;
Roots.push_back (ROOT1);
Roots.push_back (ROOT2);
Return &roots;
}
ROOT1 = 0.0;
Root2 = ratio;
Roots.push_back (ROOT1);
Roots.push_back (ROOT2);
Return &roots;
}
A * x^2 + b * x + c = 0
Number B2 = b * b;
Number FOUR_AC = 4.0 * A * C;
Number Radicand = Addwithcancellationcheck (B2,-four_ac, cesiummath::_epsilon14);
if (Radicand < 0.0)
{
Both roots is complex.
Return &roots;
}
Number q = -0.5 * Addwithcancellationcheck (b, cesiummath::sign (b) * STD::SQRT (Radicand), cesiummath::_epsilon14);
if (b > 0.0)
{
ROOT1 = q/a;
Root2 = c/q;
Roots.push_back (ROOT1);
Roots.push_back (ROOT2);
Return &roots;
}
ROOT1 = c/q;
Root2 = q/a;
Roots.push_back (ROOT1);
Roots.push_back (ROOT2);
Return &roots;
}
Number Quadraticrealpolynomial::addwithcancellationcheck (number left, number right, number tolerance)
{
Number difference = left + right;
if (Cesiummath::sign (left)! = Cesiummath::sign (right)) &&
Std::abs (Difference/std::max (Std::abs (left), Std::abs (right)) < tolerance)
{
return 0.0;
}
return difference;
}
Solving C + + implementation by one-yuan two-time equation