永野護さんへのお返事です。
> カーマイケル数の場合はどのようなプログラムにすればよいのか教えていただけないでしょうか。
前回の延長線では
!カーマイケル数
OPTION ARITHMETIC RATIONAL !有理数モード(多桁整数)
LET M=10000 !検索範囲
FOR n=2 TO M
IF PrimeQ(n)=0 THEN !合成数nが
FOR a=2 TO n-1 !底
IF GCD(a,n)=1 THEN !自身と互いに素である任意の自然数aに対して
IF MOD(a^(n-1),n)<>1 THEN EXIT FOR !a^(n-1)≡1 mod n を満たす
END IF
NEXT a
IF a=n THEN PRINT n !最後までなら
END IF
NEXT n
END
EXTERNAL FUNCTION PrimeQ(n) !素数判定 1:素数、0:素数でない
OPTION ARITHMETIC RATIONAL !有理数モード(多桁整数)
LET PrimeQ=0
IF n<2 OR n<>INT(n) THEN EXIT FUNCTION !引数を確認する
!2以上の自然数なら
IF MOD(n,2)=0 THEN !偶数なら
IF n=2 THEN LET PrimeQ=1 !2は素数
ELSE !奇数なら
LET k=3
DO WHILE k*k<=n !3~√nの奇数のみで検証する
IF MOD(n,k)=0 THEN EXIT FUNCTION !ひとつでも割り切れるものがあれば素数でない
LET k=k+2
LOOP
LET PrimeQ=1 !最後まで割り切れなければ、素数である
END IF
END FUNCTION
となりますが、多桁整数の計算のため時間を要します。
十進モードや2進モードで高速に計算するには、
関数GCDの定義とa^(n-1)のオーバーフロー対策をプログラムする必要があります。
!カーマイケル数
LET M=10000 !検索範囲
FOR n=2 TO M
IF PrimeQ(n)=0 THEN !合成数nが
FOR a=2 TO n-1 !底
IF GCD(a,n)=1 THEN !自身と互いに素である任意の自然数aに対して
IF modpow(a,n-1,n)<>1 THEN EXIT FOR !a^(n-1)≡1 mod n を満たす
END IF
NEXT a
IF a=n THEN PRINT n !最後までなら
END IF
NEXT n
END
EXTERNAL FUNCTION PrimeQ(n) !素数判定 1:素数、0:素数でない
LET PrimeQ=0
IF n<2 OR n<>INT(n) THEN EXIT FUNCTION !引数を確認する
!2以上の自然数なら
IF MOD(n,2)=0 THEN !偶数なら
IF n=2 THEN LET PrimeQ=1 !2は素数
ELSE !奇数なら
LET k=3
DO WHILE k*k<=n !3~√nの奇数のみで検証する
IF MOD(n,k)=0 THEN EXIT FUNCTION !ひとつでも割り切れるものがあれば素数でない
LET k=k+2
LOOP
LET PrimeQ=1 !最後まで割り切れなければ、素数である
END IF
END FUNCTION
EXTERNAL FUNCTION modpow(a,n,b) !a^n≡x mod b のxを返す ※nは非負整数
LET S=MOD(1,b)
DO WHILE n>0 !べき乗nを2進展開する
IF MOD(n,2)=1 THEN LET S=MOD(S*a,b) !ビットが1なら計算する
LET a=MOD(a*a,b)
LET n=INT(n/2)
LOOP
LET modpow=S
END FUNCTION
EXTERNAL FUNCTION gcd(a,b) !最大公約数
DO UNTIL b=0
LET t=b
LET b=MOD(a,b)
LET a=t
LOOP
LET gcd=a
END FUNCTION