報告。
乱数そのもののチェックはまだおわってないけどRND(x)の実装は問題ありですね
例えばこんなの
M=1879048192:C1=0:C2=0
FOR I=1 TO 10000
R=RND(M)
IF A<M/2 THEN INC C1 ELSE INC C2
NEXT
PRINT STR$(C1)+" "+STR$(C2)
大きい乱数を作って半分より大きいものと小さいものの個数を数えるだけ。
半分だから当然同じくらいの数になるはずだけど…
それでもダメなんです…
確かに4096と1しか離れていない4095を使えば「互に素」ですから周期は伸びるんですが…
今度は近すぎて乱数じゃなくなっちゃう。
こちらを動かしてみてください。(たぶんmkIIで動く)
X=0:Y=0:DIM C[16]
FOR I=0 TO 10000
GOSUB @RND:X1=(X AND 3):GOSUB @RND:X1=(X AND 3)
J=X1+X2*4:C(J)=C(J)+1
NEXT
FOR I=0 TO 15
PRINT STR$(C(I))+"/";
NEXT
END
@RND
Y=(Y+1)%4095:X=(X*117+Y)%4096
RETURN
うーん…
何処で見つけたのか、どう計算したのかわかりませんが、残念ながらそれだとアルゴリズムがダメなので最大周期が保証されてないんですよ
証明は…余白が足りないから省略。
X=0:Y=0
FOR I=0 TO 2000:FOR J=0 TO 9999
GOSUB @RND
IF X==0 AND Y==0 THEN GOTO @AAA
NEXT:NEXT
@AAA
PRINT STR$(I)+RIGHT$("000"+STR$(J),4)
こんな感じで試してみてくださいな
初期値が0,0なら4613119回で抜けてしまいます