ProgrammingCity
ソフト公開と、それに関わるいろいろ. 転送速度が遅くてごめんなさい
サイト内検索
Microsoft Silverlight を取得

ようこそ。自作ソフトを公開しています。2008/10 一部ページのアドレスが変わりました。

RSS / お気に入り追加

profile

Link

friends

ほか

何かしてくれたサイト

便利

  • Keisan
    高精度計算サイト
top > C# > 3次方程式を解く

3次方程式を解く

「解の公式は4次まである」などという言葉を聞いていたので
簡単に計算出来そうだと思っていたが、結構面倒だった。

ax^3+bx^2+cx+d 元の式を
x=X-{b\over3a} として
a(X-{b\over3a})^3+b(X-{b\over3a})^2+c(X-{b\over3a})+d=0
上のように変換し、展開し、a で割る。

0=a(X^3-{b\over{a}}X^2+{b^2\over{3a^2}}X-{b^3\over{27a^3}})+b(X^2-{2b\over{3a}}X+{b^2\over{9a^2}})+c(X-{b\over{3a}})+d
0=aX^3+(-{b^2\over{3a}}+c)X+{2b^3\over{27a^2}}-{bc\over{3a}}+d
0=X^3+(-{b^2\over{3a^2}}+{c\over{a}})X+{2b^3\over{27a^3}}-{bc\over{3a^2}}+{d\over{a}}

結果、
X^2+3pX+2q
p=-{b^2\over{9a^2}}+{c\over{3a}}
q={b^3\over{27a^3}}-{bc\over{6a^2}}+{d\over{2a}}
の形式になる。
これを使ってu, v を作る。
u=\sqrt[3]{-q+\sqrt\Delta}
v=\sqrt[3]{-q-\sqrt\Delta}
\Delta=q^2+p^3

u, v は値が3つずつある。
その中から、u * v  = -p となる u + v を選ぶ。それがX。
とりあえず絶対値の差が0に近いものを選んだ。

        static public Complex[] cubiceq(double p, double q) {
            Complex cp, cq;
            cp = new Complex(p, 0);
            cq = new Complex(q, 0);

            Complex[] u, v;
            Complex delta;
            double dtmp = p * p * p + q * q;
            delta = (dtmp< 0)
                ? new Complex(0, Math.Sqrt(-dtmp))
                : new Complex(Math.Sqrt(dtmp), 0);

            u = Complex.proot(-cq + delta, 3);
            v = Complex.proot((-cq) - delta, 3);

            Complex[] result = new Complex[3];
            int cnt3 = 0;
            for (int cnt = 0; cnt < u.Length; cnt++) {
                for (int cnt2 = 0; cnt2 < v.Length; cnt2++) {
                    if (Math.Abs(Math.Abs((u[cnt] * v[cnt2]).real) - Math.Abs(p))< 0.0001) {
                        result[cnt3++] = u[cnt] + v[cnt2];
                    }
                }
            }
            return result;
        }
        static public Complex[] cubiceq(double a, double b, double c, double d)
        {
            Complex[] res = cubiceq(-(b * b) / (9 * a * a) + c / (3 * a),
                (b * b * b) / (27 * a * a * a) - (b * c) / (6 * a * a) + d / (2 * a));

            for (int cnt = 0; cnt < 3; cnt++) {
                res[cnt].real -= (b / 3.0 );
            }
            return res;
        }

参考文献

高校数学+α p66 あたり (全頁pdf で読めるみたいです。)