一元三次方程的實數根

一元三次方程的實數根

一元三次方程的一般形式

一元三次方程的一般形式爲

ax3+bx2+cx+d=0,a0.

x=yb3a ,則原式變成
a(yb3a)3+b(yb3a)2+c(yb3a)+d=0,a(y3by2a+b2y3a2b327a3)+b(y22by3a+b29a2)+c(yb3a)+d=0,ay3by2+b23ayb327a2+by22b23ay+b39a2+cybc3a+d=0,ay3+(cb23a)y+(d+2b327a2bc3a)=0,y3+(cab23a2)y+(da+2b327a3bc3a2)=0.

如此一來二次項就不見了,化成y3+3py+2q=0 ,其中p=c3ab29a2q=d2a+b327a3bc6a2

方程y3+3py+2q=0 的實數根

Δ=q2+p3 ,則

(i)Δ>0 時,方程只有一個實根。

y=q+Δ3+qΔ3.

(ii)Δ=0 時,方程有三個實根,其中至少有兩個相等的實根。
y1=2q3,y2=y3=q3.

(iii)Δ<0 時,方程有三個不等實根。

α=13arccosqpp2 ,則

y1=2pcosα,y2=2pcos(α+120),y3=2pcos(α+240).

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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章