|
> No.4319[元記事へ]
白石 和夫さんへのお返事です。
> 私のところでもExtype12001が出ます。
> signal文で終了のシグナルを発行したのを確認しても,その時点ではまだその並行活動は終了していないかも知れません。
> Full BASICには他の並行活動の状態を調べる手段が用意されていないので,終了したかどうかはSTART文を実行してみるまでわかりません。
> EXTYPE12001の例外状態になるときは終了を待てばよいので,各start文を次のように変えれば動くと思います。
>
> 例 START PART2のとき
> DO
> WHEN EXCEPTION IN
> START PART2
> LET success=1
> USE
> IF EXTYPE=12001 THEN
> LET success=0
> WAIT DELAY 0.01
> ELSE
> exit handler
> END IF
> END WHEN
> LOOP UNTIL success=1
>
> 簡略化して
> DO
> WHEN EXCEPTION IN
> START PART3
> LET success=1
> USE
> LET success=0
> WAIT DELAY 0.01
> END WHEN
> LOOP UNTIL success=1
> でも大丈夫です(多分)。
>
> USE行の下に
> PRINT EXTYPE
> を追加して実行してみると,ときたま
> 12001
> を表示するのが観察できます。
>
有難うございました。家のPCでは安定して計算してます。
-----------------------------------------------------
!Sieve of Sundaram Prime number Counting !Ver.2.1
!素数計数関数(英: Prime-counting function)π(x)
!Paract BASICによるマルチスレッド化プログラム
DECLARE STRUCTURE STRUCT1: 2 OF NUMERIC
DECLARE STRUCTURE STRUCT4: 1 OF NUMERIC
DECLARE SHARED buff1 OF STRUCT1
DECLARE SHARED buff2 OF STRUCT1
DECLARE SHARED buff3 OF STRUCT1
DECLARE SHARED buff4 OF STRUCT4
DECLARE SHARED buff5 OF STRUCT4
DECLARE SHARED buff6 OF STRUCT4
PARACT PART1
OPTION ARITHMETIC NATIVE
DECLARE NUMERIC ST,I
LET t0=TIME
LET S=90000000001
LET E=100000000000 !pi(x)4118054813
LET ST=10000000
LET TOTAL=3722428991!9e10,3325059246,8e10,2925699539,7e10,2524038155,6e10,2119654578,5e10,1711955433,4e10,1711955433,3e10,1300005926,2e10,882206716,1e10,455052511,1e9,50847534
DECLARE EXTERNAL FUNCTION ERATOS
FOR I=S TO E STEP ST
PUT TO BUFF1 FROM I,ST
SIGNAL Ready1
DO
WHEN EXCEPTION IN
START PART2
LET success=1
USE
LET success=0
WAIT DELAY 0.01
END WHEN
LOOP UNTIL success=1
PUT TO BUFF2 FROM I,ST
SIGNAL Ready3
START PART3
PUT TO BUFF3 FROM I,ST
SIGNAL Ready5
START PART4
LET L1=ERATOS(I,I+ST/4-1)
WAIT EVENT Ready2
GET FROM BUFF4 TO L2
WAIT EVENT Ready4
GET FROM BUFF5 TO L3
WAIT EVENT Ready6
GET FROM BUFF6 TO L4
LET TOTAL=TOTAL+L1+L2+L3+L4
PRINT I;"~";I+ST-1;":";L1+L2+L3+L4;TOTAL
NEXT I
LET TM=TIME-t0
PRINT USING"####." & REPEAT$("#",2):TM;
PRINT "秒"
END PARACT
PARACT PART2
OPTION ARITHMETIC NATIVE
DECLARE NUMERIC I,ST
DECLARE NUMERIC L2
DECLARE EXTERNAL FUNCTION ERATOS
WAIT EVENT Ready1
GET FROM BUFF1 TO I,ST
LET L2=ERATOS(I+ST/4,I+ST/2-1)
PUT TO BUFF4 FROM L2
SIGNAL Ready2
END PARACT
PARACT PART3
OPTION ARITHMETIC NATIVE
DECLARE NUMERIC I,ST
DECLARE NUMERIC L3
DECLARE EXTERNAL FUNCTION ERATOS
WAIT EVENT Ready3
GET FROM BUFF2 TO I,ST
LET L3=ERATOS(I+ST/2,I+3*ST/4-1)
PUT TO BUFF5 FROM L3
SIGNAL Ready4
END PARACT
PARACT PART4
OPTION ARITHMETIC NATIVE
DECLARE NUMERIC I,ST
DECLARE NUMERIC L4
DECLARE EXTERNAL FUNCTION ERATOS
WAIT EVENT Ready5
GET FROM BUFF3 TO I,ST
LET L4=ERATOS(I+3*ST/4,I+ST-1)
PUT TO BUFF6 FROM L4
SIGNAL Ready6
END PARACT
EXTERNAL FUNCTION ERATOS(N,M)
OPTION ARITHMETIC NATIVE
LET N=N-1
LET COUNT=0
LET k8=INT(N/2)
LET M7=k8-1
LET k9=INT(M/2)
DIM A(k9-M7)
MAT A=ZER
LET S=3
LET D=4
LET k=INT(SQR(k9))*3
DO
LET B=D+S*INT((k8-D)/S)
DO UNTIL B>=k8
LET B=B+S
LOOP
FOR I=B TO k9 STEP S
LET A(I-M7)=1
NEXT I
LET S=S+2
LET D=D+3
LOOP UNTIL D>k
FOR n=1 TO k9-M7
IF (n+M7)*2+1>M THEN EXIT FOR
IF A(n)=0 THEN LET COUNT=COUNT+1
!LET Sun=(n+M7)*2+1
!PRINT Sun
NEXT n
LET ERATOS=COUNT
END FUNCTION
--------------------------------------------
1000000001 50847534
100000000000 4118054813
上記の範囲を計算すると、素数の個数が足りません。
素数の個数 精度確認の範囲
1e10 455052511
2e10 882206716
3e10 1300005926
4e10 1711955433
5e10 2119654578
6e10 2524038155
7e10 2925699539
8e10 3325059246
9e10 3722428991
--------------------------------------
1e10 455052511
2e10 882206716
1e10 間の範囲では誤差は見られませんでした。計算範囲の4分割とサンダラムの篩の1/2の数値合わせを見直しています。
http://blogs.yahoo.co.jp/donald_stinger
|
|