発掘した素数検定ツールも動き始めている

かなり仕事がはかどった.発掘した素数検定ツールも動き始めている.できることが大幅に広がった気がする.ひょっとすると「効率的な素因数分解」まで進めるかもしれない.いまやっている「べき乗の剰余数列の周期性」と「1/nの小数部の循環周期」に繋がりのあることも見えてきた.よく分からないのはPrimeTestとSeedTestだ.おそらくPrimeTestでは素数判定アルゴリズムの検証を試みているのではないかと思われるが,SeedTestのところはいまのところまったく不明だ.出力も雑多な記号の羅列のようになっていて,作成意図がまったく分からない.

先に進む前にいくつか片付けておきたい.まず,ファイルをもうひとつ作って,そこに不要になったコードを移しておこう.廃棄してしまえばそれまでだが,後日何か参照する必要が出てくる可能性もあるので温存しておいた方が無難だ.ファイル名はごみ箱としておけばよい.おそらく,現行版ではまだSieveを使っているはずだが,廃止することにしたので,PrimeTableも破棄ということになる.グローバル変数もごみ箱に移して,何かのときには復活できるようにしておいた方がよい.

PrimeTableはPFactorで使われている.PFactorは最小の約数を返す関数だ.確かに,素数はかなり疎らに存在するから全数検査というのは割が悪い.TotientFuncの論理を使って書き直してみよう.①最初に2をチェックしてその後は奇数だけを検査,②√xの範囲を検査としたのでそこそこ動作するだろう.PrimeTableはPrimeTestSubでも使われている.PrimeTableは素数テーブルなので,これがないと素数判定をランタイムで実行しなくてはならない.⇒代替としてTotient関数を使うしかない.φ値がx-1ならxは素数とみなされる.これしかないのではないだろうか?あまり割がよいとは言えないがやむを得ない.

PrimeTestSubではすべての偶数をチェック範囲に入れている.これはムダなことだ.修正が必要.⇒やってみよう.⇒修正完了した.20614132のInverseを実行したらループから抜けてこない.確かにかなり大きい数ではあるが…この数は,4.85104102370160-10^8だが.周期<20614132であるとしても相当大きなものになりそうだ.このPCでは計算できないかもしれない.⇒おそらく,これはダンプに途方もない時間が掛かっているのだろう.スクロールが止まっているので様子は見えないが,数万あるいはそれ以上の桁数のダンプを出すのは重過ぎる.⇒確かにそのようだ.ダンプを停めたら軽く動いた.

20614132程度の数なら一瞬で因数分解は終わる.これでSieveを使わずに素数判定できるようになった.現在,出力用のテキストボックスが3つあるが,出力はすべてOutボックスに出すようにしてもよいのではないか?その方が画面も簡素になる.あるいは,値を設定すると自動的にφとψを計算して表示するようにしてもよい.その方がおもしろいのではないか?1/nの値を出すのもおもしろい.NotationはOutに出力するのではなく,トグルでBベースと10進を切り替えできるようにするのがよいのではないか?そうすれば,repunitというボタンは廃止できるし,ketaも廃止できるだろう.valueの値を書き換えるという仕様はよくない.

このためにはB進数の文字列⇔数値変換ができなくてはならない.VBにConvert.ToStringという関数がある.ただし,ToStringはInt32だ.この逆変換としてConvert.ToInt32というのがある.入力ボックスに入力される値としてはInt32以上を禁止しても実用上は差し支えないのではないか?φとψを常時画面に表示するようになれば,PrimeTestは不要になる.PrimeTestの目的は φ mod ψ ≡ 0 の検証であると考えられるので,例外が発生した場合にだけ停止するようにしておけばよい.

Inverseの出力ももう少しシンプルなものにしたい.Inverseでは対象数の小数点表示を出すべきだ.周期列とφないしψの関係がくっきり出るような表示が必要だ.一番分かりづらいのがSeedTestだが,狙っているのは冪剰余列でやっているようなところではないのだろうか?べき剰余列でも,φなどを表示するべきだ.冪剰余の連続実行ボタンで,InverseやSeedTestを実行できるようにすることも考えられる.チェックがオンになっている機能を実行するようにすればよい.

Convert.ToStringはかなり動作に制限がある.引数が8ビット,つまり,1バイトの数を指定した進数に変換するというだけだ.つまり,数を一度BCDに変換して格納しておく必要がある.逆数を常時表示しておきたいのだが,表示桁数が足りない.doubleで15桁,decimalでも29桁しかない.InverseFuncで出力を停めているが,ループから抜けてこない.配列サイズオーバーが発生してしまう.とりあえず,対象数値をInt32に限定しないと無理なようだ.Int32に限定してもまだオーバーフローしてしまう.7FEFFFFF=2,146,435,071が限界ということのようだ.⇒1/nを10^m倍して固定小数点化したものを文字列に変換して出力するようにした.これなら桁数がいくら増えても表示できる.

一つおもしろいことに気付いた.n=7として,1/7を計算すると,{142857}という循環節が現れる.これを数とみなしてその逆数1/142857を取ると,この分数の循環単位は{000007}となる.つまり,{142857}と{000007}はある種の逆数のような関係になっている.ψ(n, b)=循環単位桁数であることはほぼ間違いないいが,これらを計算しているコードを見ると,ほぼ事実上同じコードになってしまっている.これでは同じ値になるのは当然だ.両者はそれぞれ独立の概念として定義され,それに従ってコーディングしているつもりだが,実質的には同一のものに別の名前を与えていただけなのだろうか?

ψは,ある基数bのもとで,b^x=1 mod n となるような最小の数として定義されている.循環単位桁数はその言葉通りの意味だ.ψの計算コードが間違っているのだろうか?どうもその気配が濃厚だ.定義によれば,B^x=1 mod n となる数 x を探しているはずなのに,循環が発生する時点での値を返している.どうも,まだ読み切れていないのだろうか?PrimeTestは単点テストと思っていたが,Bの範囲を指定してリスト出力する多点検定だった.⇒処理を中断する打ち切りボタンが必要だ.

356をInvertしてfixedの値が間違っている.前方の0がカウントされていない.⇒対処した.

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA