Skip to content

SolveCubic 實作細節

本頁為 SolveCubic - 解三次方程式 的實作細節。

ax3+bx2+cx+dax^3 + bx^2 + cx + d

分析

解三次方程式是一個複雜的問題,雖然有公式解,但很醜。

P3P_3 必有一個實數根,如果用勘根找到這個實根,那就可以將 P3P_3 化簡為 P2P_2
P2P_2 只需要用 b±b24ac2a\frac{-b \pm \sqrt{b^2 - 4ac}}{2a} 解,非常簡單。

尋找有理根

x=±{all d factors}{all a factors}x = \pm \frac{ \{ \text{all} ~ d ~ \text{factors} \} }{ \{ \text{all} ~ a ~ \text{factors} \} }

全部代進 ax3+bx2+cx+dax^3 + bx^2 + cx + d,若 =0= 0 表示找到有理根。

如果沒有任何有理數符合,那麼這個 P3P_3 不存在有理根。

尋找實數根

如果沒找到有理根,需要求得一個近似實根 ( float )。

以下會使用二分搜尋來求近似的實根,時間複雜度為 logx\log x

Step 1
如果 a<0a < 0 同乘 1-1 使 a>0a > 0

  • 如果 f(0)>0f(0) > 0,代表某個根一定 <0< 0
  • 如果 f(0)=0f(0) = 0,代表某個根一定 =0= 0
  • 如果 f(0)<0f(0) < 0,代表某個根一定 >0> 0

Step 2

  • 如果 f(0)>0f(0) > 0,檢查 f(20)f(-2^0) 的值是否 <0< 0,如果沒有就繼續檢查 f(21),f(22),f(-2^1), f(-2^2), \cdots, 直到找到一個異號區間 x[2n+1,2n]x \in [-2^{n+1}, -2^n],對這個範圍的 xx 用二分搜尋逼近 f(x)=0f(x) = 0
  • 如果 f(0)<0f(0) < 0,檢查 f(20)f(2^0) 的值是否 >0> 0,如果沒有就繼續檢查 f(21),f(22),f(2^1), f(2^2), \cdots, 直到找到一個異號區間 x[2n,2n+1]x \in [2^n, 2^{n+1}],對這個範圍的 xx 用二分搜尋逼近 f(x)=0f(x) = 0

簡化問題

現在成功的得到了 P3P_3 的一個實根 rr,因此 (xr)(x-r) 必整除 f(n)f(n)

f(x)=(xr)g(x)=0  ,  g(x)P2(R)f(x) = (x-r) g(x) = 0 ~~,~~ g(x) \in P_2(\mathbb{R})

g(x)=ax2+bx+cg(x) = a'x^2 + b'x + c',因此

f(x)=(xr)(ax2+bx+c)=ax3+(bra)x2+(crb)xrc=0f(x) = (x-r)(a'x^2 + b'x + c') = a'x^3 + (b'-ra')x^2 + (c'-rb')x - rc' = 0

=ax3+bx2+cx+d= ax^3 + bx^2 + cx + d

可知

a=a;b=ra+b;c=rb+ca' = a \quad;\quad b' = ra' + b \quad;\quad c' = rb' + c

SolveQuadax2+bx+c=0a'x^2 + b'x + c' = 0,再將計算結果與 rr 合併,即可得到 P3P_3 的三個根。

排序

SolveCubicSolveQuad 會把輸出的 2/3 Frac2/3 float 做升序排列。