このサイト
https://rohaki.main.jp/mokuji.htmlを参考に、多項式の根を求めるプログラムを書いてみました。
実装難易度高いわりにそれなりの頻度で使うんですよね。
最近はサブルーチンを細かく分割するのにハマってます(IF/FOR/WHILEの入れ子が3段ぐらいを目安に分割してる)。
'最大1000次式
DIM B[1000] 'aをpx+qで割った商
DIM C[1000] 'bをpおよびqで偏微分した値
'二次方程式を解く
'a,b,c…係数(ax^2+bx+c)
'rp,jp…正の解(実部,虚部)
'rn,jn…負の解(実部,虚部)
DEF SOLVEQUAD A,B,C OUT RP,JP,RN,JN
VAR D#=B*B-4*A*C '判別式
IF D#>0 THEN '実数解を持つ
IF B>0 THEN 'Bが正なら、正の解で分子を有理化
RP=2*C/(-B-SQR(D#)) '分子を有理化した解の公式
JP=0
RN=(-B+SQR(D#))/2/A '解の公式
JN=0
ELSE 'Bが負なら、負の解で分子を有理化
RP=(-B+SQR(D#))/2/A '解の公式
JP=0
RN=2*C/(-B+SQR(D#)) '分子を有理化した解の公式
JN=0
ENDIF
ELSE '複素数解を持つ
RP=-B/2/A
JP=SQR(-D#)/2/A
RN=-B/2/A
JN=-SQR(D#)/2/A
ENDIF
END
'aをpx+qで割った商を求める
DEF BAIRSTOW_DIV A[],B[],P,Q,N
VAR I%
B[0]=A[0]:B[1]=A[1]-P*B[0]
FOR I%=2 TO N-1
B[I%]=A[I%]-P*B[I%-1]-Q*B[I%-2]
NEXT I%
END
//bをqで偏微分した値,bをqで偏微分した値を求める
DEF BAIRSTOW_DIF B[],C[],P,Q,N
VAR I%
C[0]=B[0]:C[1]=B[1]-P*C[0]
FOR I%=2 TO N-1
C[I%]=B[I%]-P*C[I%-1]-Q*C[I%-2]
NEXT I%
END
(続く)