検定ミスが見つかった
|
移植するのに当たって、現在まで得られている素数を再度調べた。と、実は一部で素数を飛ばして計算していることが解った。
今回のプログラムは完全積み上げ型を指向していたので何処かでミスすると以後の計算が全て間違った結果になる危険性が有った。だから、基礎になる今まで得た素数を再度検定したのだが何故か100万個あたりが怪しい。ここは90万個あたりからデータが欠落しているのだ。ここまで戻って新しいプログラムを動かそうと思ったのは既に300万個まで来ていた段階なのだが、計算ミスはしょうがない。現在ここからリスタートしている。 それにしても一日かかって10万件しか計算出来ない。このコラムを書き始めた状態に戻るには1ヶ月くらい時間が必要かもしれない。そんな感じで再度素数計算を始めた。 |
今回のプログラムの基本的考え方
|
経験から思ったほど数字が大きくなっても素数は減らない。「思ったほど」ってのは個人差があると思うが最初の頃は「世界最高の素数ってパソコンが2、3日動いた後にぱっと画面に表示されるのではないか」と思っていた。しかし、実際には最初数千までの段階では急激に素数の出現率が下がるが、その後はほとんど同じ様な割合で素数が出現する。
もっとも理論通りに少しは減る。しかしその減り方は劇的では無く、徐々にって感じだ。 そこで見つかった素数を貯めておいても貯めるファイルが大きくなってパソコンの外部メモリーをオーバーフローさせてしまう。今回使えるパソコンのハードディスクは450Mbyte程有るので、得られた素数を貯めるのは十分だ。ただし、途中での計算ミス等でもリスタートできるように結果を1ファイルに集約させるのでは無く分散させたいと思う。 また、1Mbyteのramファイルが使えるのでこれは利用しない手は無い。ramファイルの利用によってハードディスクを回さなくてもファイルを書き出せる。ただ、その上限は1Mbyteまでだ。 そこで考えたのは得られた素数をテーブルとしてメモリーに許される上限まで読み込む。これはおおむね8000個までであった。それ以上の素数はファイルとして必要が有れば読み込む。もちろんこの読み込まれる素数は既に得られた素数でもある。得られた素数はramファイルの中でappend(追加)するファイルに書き込む。このファイルを時々ハードディスクに待避して10万件毎のファイルとして蓄積する。 そんな方法で作られたのが以下のプログラム 10 'save "sosu.bas",a 20 '************************************************** 30 '* BASICの標準関数での最大の素数を求める * 40 '************************************************** 50 DEFDBL A-S 60 STIME$=TIME$ 70 MAX=8000 80 DIM SOSU(MAX) 90 DIM FIL$(100) 100 GOSUB *STPRG 110 A=A+2 120 SOSU=0 130 GOSUB *SOSUCHK 140 IF SOSU=1 THEN ELSE GOTO 290 150 DMAX=DMAX+1 160 AS=A-APRO 170 IF AS>100000! THEN GOTO 190 180 IF AS>AMAX THEN AMAX=AS 190 rtu=dmax/a 191 PRINT USING "No=##,###,### A=###,###,### pro=###";DMAX,A,AS; 200 PRINT USING " max=#### %=#.##### ";AMAX,rtu*100; 210 PRINT USING "& & & &";STIME$,TIME$ 220 APRO=A 230 OPEN "C:\0_sosu.dat" FOR APPEND AS #1 240 PRINT #1,RIGHT$(STR$(A),LEN(STR$(A))-1)+","; 250 CLOSE #1 260 A$=INKEY$ 270 IF A$="Z" THEN GOTO 300 280 IF A$="z" THEN GOTO 300 290 GOTO 110 300 *FIN 310 CLOSE 320 END 330 *STPRG 340 '************************************************** 350 '* 初期の既知の素数を読み込む * 360 '************************************************** 370 PRINT "Phase 1 テーブル(1)読み込み" 380 OPEN "a:\bas\LOG\00008K.dat" FOR INPUT AS #1 390 IF EOF(1) THEN GOTO 450 400 INPUT #1,SOSU 410 DMAX=DMAX+1 420 IF DMAX>MAX THEN GOTO 450 430 SOSU(DMAX)=SOSU 440 GOTO 390 450 CLOSE #1 460 PRINT "Phase 1 テーブル(1)読み込み終了" 470 PRINT "Phase 2 テーブル(2)読み込み開始" 480 OPEN "C:\0_sosu.dat" FOR INPUT AS #1 491 DMAX=1408000 '* 設定変更注意 500 IF EOF(1) THEN GOTO 550 510 INPUT #1,ASOSU 520 DMAX=DMAX+1 530 A=ASOSU 540 GOTO 500 550 CLOSE 560 PRINT "Phase 2 テーブル(2)読み込み終了" 570 FIL$(1)="LOG\00108K.dat" 580 FIL$(2)="LOG\00208K.dat" 590 FIL$(3)="LOG\00308K.dat" 600 FIL$(4)="LOG\00408K.dat" 610 FIL$(5)="LOG\00508K.dat" 620 FIL$(6)="LOG\00608K.dat" 630 FIL$(7)="LOG\00708K.dat" 640 FIL$(8)="LOG\00808K.dat" 650 FIL$(9)="LOG\00908K.dat" 660 FIL$(10)="LOG\01008K.dat" 670 FIL$(11)="LOG\01108k.dat" 680 FIL$(12)="LOG\01208K.dat" 690 FIL$(13)="LOG\01308K.dat" 700 FIL$(14)="LOG\01408K.dat" 710 FIL$(15)="LOG\01508K.dat" 720 FIL$(16)="LOG\01608K.dat" 730 FIL$(17)="LOG\01708K.dat" 740 FIL$(18)="LOG\01808K.dat" 750 FIL$(19)="LOG\01908K.dat" 760 FIL$(20)="LOG\02008K.dat" 770 FIL$(21)="LOG\02108K.dat" 780 FIL$(22)="LOG\02208K.dat" 790 FIL$(23)="LOG\02308K.dat" 800 FIL$(24)="LOG\02408K.dat" 810 FIL$(25)="LOG\02508K.dat" 820 FIL$(26)="LOG\02608K.dat" 830 FIL$(27)="LOG\02708K.dat" 840 FIL$(28)="LOG\02808K.dat" 841 FIL$(29)="LOG\02908K.dat" 850 RETURN 860 *SOSUCHK 870 '************************************************** 880 '* テーブルを利用して素数を検定する * 890 '************************************************** 900 FOR ZI=2 TO MAX 920 AW=A-INT(A/SOsu(zi))*SOsu(zi) 930 IF AW=0 THEN GOTO 1140 940 NEXT ZI 950 '************************************************** 960 '* ファイルの素数で値を検定する * 970 '************************************************** 980 IF A>SOSU(7999)*SOSU(8000) THEN ELSE GOTO 1120 990 FILNO=0 1000 FILNO=FILNO+1 1010 IF FIL$(FILNO)="" THEN GOTO 1120 1020 PRINT FIL$(FILNO)+" open" 1030 OPEN FIL$(FILNO) FOR INPUT AS #1 1040 IF EOF(1) THEN GOTO 1100 1050 INPUT #1,ASOSU 1060 IF ASOSU > A/2 THEN GOTO 1120 1070 AW=A-INT(A/ASOSU)*ASOSU 1080 IF AW=0 THEN GOTO 1130 1090 GOTO 1040 1100 CLOSE #1 1110 GOTO 1000 1120 SOSU=1 1130 CLOSE #1 1140 RETURN |
戻る | 次へ |