1000桁モードでの数値演算の桁あふれ
1000桁モードでの数値演算の桁あふれ 山中和義 2008/07/28 20:24:41
├KK62526です。 KK62526 2008/07/29 22:00:17
│└この件が解決した後、報告しようと思ってい... 山中和義 2008/07/30 10:10:51
│ └的確なご指摘、どうもありがとうございます... KK62526 2008/07/31 08:30:34
├1000桁モードでの数値の指数部の扱いが構文... 山中和義 2008/07/30 10:02:43
│└現象の解析、どうもありがとうございました... KK62526 2008/07/31 08:31:32
└再帰的な書き方に慣れるために KK62526 2008/08/01 00:28:51
1000桁モードでの数値演算の桁あふれ 山中和義 2008/07/28 20:24:41 ツリーへ
1000桁モードでの数値演算の桁あふれ
|
返事を書く ノートメニュー
|
山中和義 <drdlxujciw> 2008/07/28 20:24:41
|
下記の2つのプログラム(πをn桁もとめる)で動作が異なります。
プログラム1では、n=194以上で桁あふれが発生します。
●プログラム1
OPTION ARITHMETIC decimal_high !OPTION ARITHMETIC RATIONAL
INPUT PROMPT "計算したい桁数 ": n PRINT "円周率を";n;"桁求める。"
LET q1 = 1 LET r1 = 180 LET t1 = 60 LET i1 = 2
FOR i = 1 TO n LET u1 = 3 * (3 * i1 + 1) * (3 * i1 + 2) LET y1 = INT((q1 * (27 * i1 - 12) + 5 * r1) / (5 * t1) ) PRINT USING "#": y1; LET q2 = 10 * q1 * i1 * (2 * i1 - 1) LET r2 = 10 * u1 * (q1 * (5 * i1 - 2) + r1 - y1 * t1) !<----- LET t2 = t1 * u1 LET i2 = i1 + 1 LET q1 = q2 LET r1 = r2 LET t1 = t2 LET i1 = i2 NEXT i
END
●プログラム2
OPTION ARITHMETIC decimal_high !OPTION ARITHMETIC RATIONAL
PUBLIC NUMERIC n
INPUT PROMPT "計算したい桁数 ": n PRINT "円周率を";n;"桁求める。"
CALL g(1,180,60,2)
PRINT PRINT PI !検算
END
EXTERNAL SUB g(q,r,t,i) OPTION ARITHMETIC decimal_high !OPTION ARITHMETIC RATIONAL LET u=3*(3*i+1)*(3*i+2) LET y=INT((q*(27*i-12)+5*r)/(5*t)) PRINT USING "#": y; IF i>n THEN EXIT SUB CALL g(10*q*i*(2*i-1), 10*u*(q*(5*i-2)+r-y*t), t*u, i+1) END SUB
|
├KK62526です。 KK62526 2008/07/29 22:00:17 ツリーへ
Re: 1000桁モードでの数値演算の桁あふれ
|
返事を書く ノートメニュー
|
KK62526 <vrgekmpzvy> 2008/07/29 22:00:17
|
KK62526です。
山中さん。円周率計算に関する件、ご教示 どうもありがとうございました。 当方でもプログラム2で、1000桁の計算でも、 桁あふれを起こさないことを確認いたしました。
こちらのプログラムの方が、もともとの Gibbonsによるこつこつアルゴリズムを 十進BASICに移植したことが分かりやすく、 はるかに見通しがすっきりしております。
私のような初心者にとって、ベテランの方から 直接レスポンスを頂けますと、とても励みに なります。どうもありがとうございました。
|
│└この件が解決した後、報告しようと思ってい... 山中和義 2008/07/30 10:10:51 ツリーへ
Re: KK62526です。
|
返事を書く ノートメニュー
|
山中和義 <drdlxujciw> 2008/07/30 10:10:51
|
この件が解決した後、報告しようと思っていました。
オリジナルのプログラムは ・無限の多桁整数 ・無限の再帰呼出し を前提にしているようですので、
スタックのオーバーフローが発生しない、繰り返しのプログラム(KK62526さんのプログラム)を、 有理数モードで実行するのがいいかと思います。
|
│ └的確なご指摘、どうもありがとうございます... KK62526 2008/07/31 08:30:34 ツリーへ
Re: この件が解決した後、報告しようと思ってい...
|
返事を書く ノートメニュー
|
KK62526 <vrgekmpzvy> 2008/07/31 08:30:34
|
的確なご指摘、どうもありがとうございます。
ご指摘の通り、Haskell言語は、無限の取り扱いに関して、 ・無限の多桁整数 ・無限の再帰呼出し という特徴を有しています。有限の結果を得たい 場合は、 ・まず、無限の関係式(漸化式など)を書き下す。 ・ついで、ほしい有限の部分を切り出す。 というアプローチを取ります。
今後、Haskell言語のプログラムを十進BASICに移植 する際にも、気をつけたいと思います。 ありがとうございました。
|
├1000桁モードでの数値の指数部の扱いが構文... 山中和義 2008/07/30 10:02:43 ツリーへ
Re: 1000桁モードでの数値演算の桁あふれ
|
返事を書く ノートメニュー
|
山中和義 <drdlxujciw> 2008/07/30 10:02:43
|
1000桁モードでの数値の指数部の扱いが構文により異なるようです。
この現象で桁あふれが発生しているようです。
OPTION ARITHMETIC decimal_high
LET a=1e1000
!LET b=1e1009 !定数 仮数と指数
!LET b=a*1000000000 !LET文の式
DEF f(a)=a*1000000000 !関数 !LET b=f(a)
FUNCTION ff(a) LET ff=a END FUNCTION !PRINT ff(a*1000000000) !関数の引数
!SELECT CASE a*1000000000 !CASE文の式 !CASE 1 !CASE ELSE !END SELECT
SUB g(a) PRINT a END SUB CALL g(a*1000000000) !サブルーチン文の引数
IF a*1000000000>0 THEN LET c=1 !条件式
END
|
│└現象の解析、どうもありがとうございました... KK62526 2008/07/31 08:31:32 ツリーへ
└再帰的な書き方に慣れるために KK62526 2008/08/01 00:28:51 ツリーへ
Re: 1000桁モードでの数値演算の桁あふれ
|
返事を書く ノートメニュー
|
KK62526 <vrgekmpzvy> 2008/08/01 00:28:51
|
再帰的な書き方に慣れるために
十進BASICでも、再帰的な記述に慣れることが必要と 感じました。円周率の計算に関して、何かよい例が ないか考えましたところ、Binary Splittingが最適 と思い至り、新たにコンテンツを増やしてみました。
Binary Splittingは、高速に級数の和をとるときに 必須のテクニックで、円周率の計算でも、しばしば 用いられます。
URLアドレスを示します。 http://www14.ocn.ne.jp/~kk62526/pi/BinSplit.html PiChudnovsky.BAS......Chudnovskyの無限級数の計算(非再帰版) PiChudnovskyR.BAS.....Chudnovskyの無限級数の計算(再帰版) PiTakano_MadhavaGregoryLeibniz.BAS....高野の公式の計算(非再帰版) PiTakano_MadhavaGregoryLeibnizR.BAS...高野の公式の計算(再帰版) PiTakano_Euler.BAS....高野の公式の計算(非再帰版) PiTakano_EulerR.BAS...高野の公式の計算(再帰版)
よろしくお願い申し上げます。
|
インデックスへ
EXIT
新規発言を反映させるにはブラウザの更新ボタンを押してください。