エラー報告

 投稿者:五十嵐真人メール  投稿日:2009年10月 9日(金)20時16分47秒
  十進BASICのプログラムを有理数モードで実行した時に以下のようなエラーが発生しました。

1、プログラム

OPTION ARITHMETIC RATIONAL
LET n=1987829
!1987829は素数。したがってMOD(3^(n-1),n)=1のはずです。
PRINT MOD(3^(n-1),n)
END

2、実行結果

836640 !本来はフェルマーの小定理より1となるはずです。

べき指数は-2147483647~2147483647の範囲の整数ならよいはずなのですが、


有理数モード
多桁の有理数の計算ができます。
計算結果は仮分数形で表示します。
ただし,入力やDATA文にこの形式は使えません。
べき乗演算では,べき指数は-2147483647~2147483647の範囲の整数に限定されます。
 

Re: エラー報告

 投稿者:白石 和夫  投稿日:2009年10月10日(土)07時53分43秒
  > No.626[元記事へ]

ご報告ありがとうございます。
調べてみます。
 

Re: エラー報告

 投稿者:山中和義  投稿日:2009年10月10日(土)12時16分13秒
  > No.627[元記事へ]

次のプログラムでは、PRINT文で表示せずエラーとなります。
LET n=1987829
LET p=3^(n-1)
LET t=p-INT(p/n)*n
PRINT -1 !trace
PRINT t !←←←←← ここで実行時内部エラーが発生する
LET t=MOD(p,n)
PRINT -2 !trace
PRINT t
END

実行結果
-1
LET n=1987829
LET p=3^(n-1)
LET t=MOD(p,n)
PRINT -1 !trace
PRINT t !←←←←← 表示される数値が正しくない
LET t=p-INT(p/n)*n
PRINT -2 !trace
PRINT t !←←←←← ここで実行時内部エラーが発生する
END

実行結果
-1
 836640
-2
 

Re: エラー報告

 投稿者:白石 和夫  投稿日:2009年10月10日(土)20時56分29秒
  > No.627[元記事へ]

原因はアセンブラでjecxzとすべきところがjcxzになっていたことでした。
近日中に修正版を作ります。
 

Re: エラー報告

 投稿者:五十嵐真人メール  投稿日:2009年10月14日(水)18時42分41秒
  > No.629[元記事へ]

白石 和夫 先生、山中和義さんへのお返事です。

> 原因はアセンブラでjecxzとすべきところがjcxzになっていたことでした。
> 近日中に修正版を作ります。


先日、エラー報告したものです。早い回答ありがとうございました。
私は、数論の数値計算をするのが趣味で、それを簡単に計算できる十進BASICには大変、お世話になっています。
開発してくださった。白石 和夫 先生には本当に感謝してます。

追伸

mod(3^(p-1),p)の計算ですが、

let s=1
for k=1 to p-1
let s=mod(s*3,p)
next k

とすれば高々3(p-1)の大きさの数が計算できるコンピュータで計算できます.

そうすれば、時間はかかるものの、十進モードで計算が可能です。
もう少し、剰余計算の公式などを駆使すれば、1000桁モードで有理数モードよりも早く計算できます。

このような考慮が私にも必要だったと思います。
 

Re: エラー報告

 投稿者:山中和義  投稿日:2009年10月14日(水)19時08分17秒
  > No.648[元記事へ]

五十嵐真人さんへのお返事です。

> mod(3^(p-1),p)の計算ですが、

べき乗を2進展開して計算すれば、掛け算の回数が減ります。
LET t0=TIME
LET p=1987829
PRINT modpow(3,p-1,p)
PRINT "計算時間=";TIME-t0

LET t0=TIME
LET s=1
FOR k=1 TO p-1
   LET s=MOD(s*3,p)
NEXT k
PRINT s
PRINT "計算時間=";TIME-t0

END

EXTERNAL FUNCTION modpow(a,n,b) !a^n≡x mod b のxを返す ※nは非負整数
IF n<0 OR n<>INT(n) THEN !非負整数以外なら
   PRINT "modpow関数でパラメータが不適当です。"
   STOP
ELSE
   LET S=1
   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 IF
END FUNCTION
 

Re: エラー報告

 投稿者:いがらしまなとメール  投稿日:2009年10月18日(日)04時37分23秒
  > No.649[元記事へ]

山中和義さんへのお返事です。

modpow関数はすばらしいですね。
ありがとうございます。

定理1

p<1373653の場合

modpow(2,p-1,p)=1 かつ modpow(3,p-1,p)=1ならばpは素数です。

定理2

p<25326001の場合

modpow(2,p-1,p)=1 かつ modpow(3,p-1,p)=1 かつ modpow(5,p-1,p)=1 ならばpは素数です。


modpow関数によって、高速に素数判定ができます。
早くそれがどの程度早いのかやってみたいです。
 

戻る