一元二次方程求解C++实现
2014-11-21 11:15
447 查看
-----------------------------------------------------------------------------------------------------------------------------
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 are complex.
return &roots;
}
// Both roots are 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 are 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;
}
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 are complex.
return &roots;
}
// Both roots are 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 are 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;
}
相关文章推荐
- 八皇后问题求解----C++实现
- 面试题之丑数的C++实现求解(孤陋寡闻了,才知道丑数这么high的东东)
- C++实现动态规划求解最长公共子序列
- 利用模拟退火算法求解TSP问题(C++实现)
- 【高级算法】单纯形法求解线性规划问题(C++实现)
- 八皇后(或n皇后)c++的一种求解实现
- Guass列主元、平方根法、追赶法求解方程组的C++实现
- 【c++程序】求解一元二次方程
- C++实现求解最大公约数和最小公倍数
- 用c++代码实现贪心算法求解最短路径问题
- C++中实现表达式的求解
- 求解最长递增子序列长度|动态规划+二分查找:C\C++实现
- 利用C++求解一元二次方程
- 一元四次方程求解C++实现
- 动态规划之最长公共子序列的求解(C++实现)
- 非线性方程组求解算法的C++实现
- 回溯法求解数独(C++实现)
- 高斯消元法求解一元多次方程 C/C++实现
- C++实现求解逆矩阵
- 求解数独的C++实现