一元三次方程的实数根
程序员文章站
2022-05-09 13:33:13
...
一元三次方程的实数根
一元三次方程的一般形式
一元三次方程的一般形式为
令
如此一来二次项就不见了,化成
方程y3+3py+2q=0 的实数根
令
令
C++代码实现
// π
const double PIE = 3.1415926535897932384626433832795;
// 求一个实数的立方根
static double SolveCubicRoot(double value);
// 求一元一次方程的实根:ax+b=0
static std::vector<double> SolveLinearEquation(double a, double b);
// 求一元二次方程的实根:ax^2+bx+c=0
static std::vector<double> SolveQuadraticEquation(double a, double b, double c);
// 求一元三次方程的实根:ax^3+bx^2+cx+d=0
std::vector<double> SolveCubicEquation(double a, double b, double c, double d)
{
// 判断三次项系数是否为零
if (a == 0)
{
return SolveQuadraticEquation(b, c, d);
}
std::vector<double> root;
// 系数
double p = (c / a - b * b / (3 * a * a)) / 3;
double q = (d / a + 2 * b * b * b / (27 * a * a * a) - b * c / (3 * a * a)) / 2;
double diff = -b / (3 * a);
// 判别式
double delta = p * p * p + q * q;
if (delta > 0)
{
// 方程只有一个实根
double sqrtDelta = sqrt(delta);
root.push_back(SolveCubicRoot(-q + sqrtDelta) + SolveCubicRoot(-q - sqrtDelta));
}
else if (delta < 0)
{
// 方程有三个不等的实根
double angle = acos(-q * sqrt(-p) / (p * p)) / 3;
root.push_back(2.0 * sqrt(-p) * cos(angle));
root.push_back(2.0 * sqrt(-p) * cos(angle + 2 * PIE / 3));
root.push_back(2.0 * sqrt(-p) * cos(angle + 4 * PIE / 3));
}
else
{
// 方程有三个实根,其中至少有两个相等的实根
if (q == 0)
{
root.push_back(0);
}
else
{
root.push_back(SolveCubicRoot(q));
root.push_back(-2 * SolveCubicRoot(q));
}
}
// 将结果加上余量
for (int i = 0, maxSize = root.size(); i < maxSize; ++i)
{
root[i] += diff;
}
return root;
}
double SolveCubicRoot(double value)
{
return value > 0 ? pow(value, 1.0 / 3) : -pow(-value, 1.0 / 3);
}
std::vector<double> SolveLinearEquation(double a, double b)
{
std::vector<double> root;
// 判断一次项系数是否为零
if (a != 0)
{
root.push_back(-b / a);
}
return root;
}
std::vector<double> SolveQuadraticEquation(double a, double b, double c)
{
// 判断二次项系数是否为零
if (a == 0)
{
return SolveLinearEquation(b, c);
}
std::vector<double> root;
// 计算判别式
double delta = b * b - 4 * a * c;
if (delta > 0)
{
// 方程有两个不等的实根
root.push_back((-b + sqrt(delta)) / (2 * a));
root.push_back((-b - sqrt(delta)) / (2 * a));
}
else if (delta == 0)
{
// 方程有两个相等的实根
root.push_back(-b / (2 * a));
}
return root;
}
上一篇: web框架-flask方式添加路由