超冪という結構扱いづらい素材が出てきたので,調理してみることにする.久留島喜内で実装しているべき乗剰余数列に関わりがあるので,追加機能としてここに組み込んでみよう.方式を考える.とりあえず,ボタンを一つ追加して,ボタンを押すとα^^e % γ が実行できるようにできればよい.その前にアルゴリズムを定式化しておく必要がある.処理は2段階で実施される.フェーズⅠではべき乗剰余数列を生成して,その周期を取り出してどこかに格納しておく.フェーズⅡではこの周期を取り出して逐次指数を計算し,最後にべき乗を実行してその剰余を計算するという段取りになる.
- フェーズⅠ
- 対象整数α,べきの段数ε,剰余演算の除数γが与えられる
- カウンタ i=0 を初期化し,k=γ, a=α とする
- #(i)=a%k とする // 次回の基数となる
- #(i)*%k のべき剰余数列と周期を取り出し@(i)とする // 次回の除数
- k = @(i), a=#(i),i++
- i ≧ε なら終了,ステップ3から繰り返し
- フェーズⅡ:この処理は再帰関数として実装する
- CalcPower(depth, base, divisor) as integer
base = #(depth),DV=@(depth)
return base^CalcPower(depth—) % DV - 呼び出し:result = CalcPower(ε, α, γ)
さて,べき乗剰余数列を生成しているルーチンを探さなくてはならない.ResidueFuncPro(num As BigInteger, γ As Int64, silent As Boolean)というのがあった.ただし,これには戻り値がない.(num As BigInteger, γ As Int64, silent As Boolean)は戻り値でketaを返している.ketaというのは循環部の桁数だから,剰余数列の周期と一致する.ResidueFuncProで戻り値を返すようにしてしまうのが一番早いのではないだろうか?このプログラムではGUIのパーツを積極的にパラメータとして用いているので,ketaの値はketa_Nに入っているはずだ.
フェーズⅠは大体動くようになった.一番最後の段で#=0になってしまうというのが不審な点だ.@23→@11→@5→まではよいのだが,その後,@2になるべきところで,@=1になってしまう.基数の方は#2→3→5→4→ と正しく推移している.@は @=a%kで計算されるが,a=5, k=5で割り切れてしまうためだ.いや,解説文の中でも#=5, @=5というタイミングはある.⇒1箇所間違えていた.これで動作するようになった.出力は
B()→2 3 5 4 1
C()→23 11 5 2 1
だ.それはそれでよいのだが,一つかなり奇妙なことが起きているのに気付いた.B,Cともに1になったあと,Bは0,Cは1が連続するようになる.Bは基数でCは除数だ.つまり,この塔は先端に達するとそれ以上成長しなくなるのではないか?