円周率の計算 〜1万桁程度 |
シャープの式 収束は遅い。
π/6=atn(1/√3)
atn(x)=x-(x^3)/3+(x^5)/5-(x^7)/7+・・・
=x(1-x^2/3+x^4/5-x^6/7+・・・ :x=1/√3
π=2*√3・(1-1/3・3+1/3^2・5-1/3^3・7・・・)
tan(π/a)=b/√c a,b,cは正の整数となるものは
以下、2つだけ。
tan(π/4)=1
tan(π/6)=1/√3
尚、tan(π/3)=√3は、収束しないので円周率計算には使えない。
!■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
! シャープの式による計算 100桁処理版
!
!tan(π/6)=1/√3
!atn(x)=x-(x^3)/3+(x^5)/5-(x^7)/7+・・・
!
=x(1-x^2/3+x^4/5-x^6/7+・・・
!x=1/√3
!
!
π=2*√3・(1-1/3・3+1/3^2・5-1/3^3・7・・・)
!
!■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
OPTION
ARITHMETIC RATIONAL
OPTION base 0
do
INPUT prompt "桁数=":KTA_2
IF
KTA_2/1000<>INT(KTA_2/1000) THEN PRINT "1000桁単位で入力してください"
loop until
KTA_2/1000=INT(KTA_2/1000)
! 初期設定――――――――――――――――――――――――――
LET
BLOKS=100
LET JJJ=10^BLOKS
LET QQ=JJJ-1
LET KTA=KTA_2/BLOKS*1.4
!40%マージン
print "計算開始時刻=";date$&" "&time$
let
T1$=time$
!print "桁数=";KTA_2
! ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
!
――配列を準備する―商・余・Σ・基底――――――――――――――――――――――――
dim
SYO(KTA*2),JOYO(KTA*2),Σ(KTA*2),BASE(KTA*2),RT3(KTA*2),Z(KTA*2)
dim
XN0(KTA*2),XN1(KTA*2),A(KTA*2),XN02(KTA*2)
dim
AXN02(KTA*2),AXN02m3(KTA*2),AXN02m3X(KTA*2)
dim OPT5(KTA*2)
!
――――――――――――――――――――――――――――――――――――――――
GOSUB 10000
!√3の計算
!級数部分の計算
! π=2*√3・(1-1/3・3+1/3^2・5-1/3^3・7・・・)
!
■■■(1-1/3・3+1/3^2・5-1/3^3・7・・・)■■■■
LET BASE(0)=1
LET Σ(0)=1
LET
kou=0
DO
LET kou=kou+100 !(2kou-1)・3^kou≒KTA_2桁数 となるkou
!
log(2*kou-1)+kou*log3>KTA_2
! kou>KTA_2/log3=KTA_2/0.477
loop until
kou>KTA_2/0.477
PRINT "kou=";kou
FOR k=2 to kou
GOSUB 1000
!resetする SYO JOYO
for I =0 to KTA
LET JOYO(I)=BASE(I)
!前のBASEをLoadする
! PRINT "B:";BASE(I)
NEXT I
! 3の割算を先に処理
LET
DIV_X=3 !3で割る
GOSUB 600 !SYOに答えが帰ってくる
! '割ったあと ベースを保管
for I =0 to
KTA
LET BASE(I)=SYO(I)
LET JOYO(I)=SYO(I)
NEXT I
LET DIV_X=2*k-1
!2*k-1で割る
GOSUB 600 !SYOに答えが帰ってくる
! ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆
for I =0
to KTA
! PRINT "k=";k
! PRINT "SYO(I)=";SYO(I)
LET
Σ(I)=Σ(I)+(-1)^(k-1)*SYO(I)
! PRINT "Σ(I)=";Σ(I)
NEXT I
next
k
!桁処理
GOSUB 800 !桁借り
GOSUB 900 !桁上げ
500
FOR I=0 TO
KTA
LET RT3(I)=XN0(I)
NEXT I
!√3部分の計算
for I =0 to KTA
FOR
J=0 to KTA
if I+J=<KTA then LET Z(I+J)=Σ(I)*2*RT3(J)+Z(I+J)
NEXT
J
NEXT I
for I=0 to KTA
LET Σ(I)=Z(I)
NEXT I
GOSUB 900
!桁上げ
!印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷
PRINT
"π計算終了時刻=";date$;" ";time$
PRINT ""
print str$(Σ(0));"."
for I=1 TO
KTA
LET p$=repeat$("0",100-len(str$(Σ(I))))&str$(Σ(I))
print
MID$(p$,1,10);" ";MID$(p$,11,10);" ";MID$(p$,21,10);" ";MID$(p$,31,10);"
";MID$(p$,41,10);" ";
print MID$(p$,51,10);" ";MID$(p$,61,10);"
";MID$(p$,71,10);" ";MID$(p$,81,10);" ";MID$(p$,91,10);" "
if int(I/10)=I/10
then print I*100;"桁目"
next
I
!印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷
STOP
600 ! *DIV_X
!
■■■■■■■■■■割算■■■■■■■■■■■■■■■■■■■■■■■■
!
*******ソロバン・ルーチン開始*********************
for I= 1 to KTA
! 商を計算
LET
SYO(I)=int((JJJ*JOYO(I-1) + JOYO(I)) / DIV_X)
! 余りを算出
LET
JOYO(I)=(JJJ*JOYO(I-1) + JOYO(I))-SYO(I)*DIV_X
next I
!
******ソロバン・ルーチン終了!!******************
! ***商の結果を余りへ置換え*****
for I=1 to
KTA
LET JOYO(I) =SYO(I)
next I
!
***置換え終了!****************
return
800 ! *KETASYORI
!
■■■■■■■■■負の数になるときの桁借りルーチン■■■■■■■■■■■■■
DO
LET f_ken=0
for K_D=1 TO
KTA*2
if Σ(K_D)<0 then
LET Σ(K_D-1)=Σ(K_D-1)-1 !上から借りて
LET
Σ(K_D)=Σ(K_D)+JJJ !その桁に足す
LET f_ken=1
end if
NEXT K_D
loop while
f_ken=1
return
! ■■■■■■■■■桁借りルーチン2 終了!■■■■■■■■■■■■■■■■■
!
■桁上げ処理■■■■■■■■■■■■■
900 ! *KEA_UP
FOR G_KTA=KTA to 1 step -1
LET
Σ(G_KTA-1)=Σ(G_KTA-1)+int(Σ(G_KTA) / JJJ)
LET Σ(G_KTA)=MOD( Σ(G_KTA) , JJJ )
next G_KTA
return
! ■■■■■■■■■■■■■■
!
■■リセットルーチン■■■■■
1000 ! *RE_SET
for I =0 to KTA
LET SYO(I)=0
LET
JOYO(I)=0
next I
return
! ■■■■■■■■■■■■■■■
10000
!■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
! √3の計算
百桁区切り √3の計算 百桁区切り √3の計算 百桁区切り √3の計算 百桁区切り √3の計算 百桁区切り √3の計算 百桁区切り
!
1/√3の漸化式
! Xn+1: = 1.5*Xn*(1 - Xn^2)
!
LET KS=0
GOSUB 20000 !
まず初期化
DO
LET KS=KS+1
loop while KTA > 2^(KS-5)
print
"KS=";KS+1
for K=0 to KS+1
print "計算";K;"回目";TIME$
GOSUB 10100
next
K
!最終計算 √3=3×(1/√3)
FOR I=0 to KTA
LET XN0(I)=3*XN0(I)
next
I
! 桁処理 --桁上げ処理
Do
LET OBF=0
for I= KTA TO 1 step -1
LET
XN0(I-1)=XN0(I-1)+int(XN0(I)/10^100)
LET
XN0(I)=XN0(I)-10^100*int(XN0(I)/10^100)
if XN0(I)>10^100 then LET
OBF=1
NEXT I
loop while
OBF=1
!印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷
print
"√3の計算終了時刻=";date$;" ";time$
!印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷印刷
return
10100 !
! Xn+1: = 1.5*Xn*(1 - Xn^2)
!
@Xn^2の計算
for I=0 TO KTA
for J=0 TO KTA-I
LET
XN02(I+J)=XN0(I)*XN0(J)+XN02(I+J)
next J
next I
! A1*Xn^2の計算
!
for I=0 TO KTA
! for J=0 TO KTA-I
! LET
AXN02(I+J)=A(I)*XN02(J)+AXN02(I+J)
! next J
! next I
! B1−1 *
Xn^2の計算
LET AXN02m3(0)=1
for I=0 TO KTA
LET
AXN02m3(I)=AXN02m3(I)-XN02(I) ! 係数1のため A項の計算を飛ばして
next I
! CXn*(1 -
Xn^2)の計算
for I=0 TO KTA
for J=0 TO KTA-I
LET
AXN02m3X(I+J)=XN0(I)*AXN02m3(J)+AXN02m3X(I+J)
next J
next I
!
D1.5*Xn*(1 - Xn^2)の計算
for I=0 TO KTA
for J=0 TO KTA-I
LET
XN1(I+J)=AXN02m3X(I)*OPT5(J)+XN1(I+J)
! LET
XN1(I)=AXN02m3X(I)*1.5
next J
next I
11000 ! 桁処理1
--負記号の削除
DO
LET MNSF=0
if XN1(1)<0 then
LET
XN1(0)=XN1(0)+int(XN1(1)/10^100)-1
LET
XN1(1)=XN1(1)-10^100*int(XN1(1)/10^100)+10^100
end if
for I=BLOCK TO 1
step -1
if XN1(I)<0 then
LET MNSF=1
LET
XN1(I-1)=XN1(I-1)+int(XN1(I)/10^100)-1
LET
XN1(I)=XN1(I)-10^100*int(XN1(I)/10^100)+10^100
end if
NEXT I
LOOP while
MNSF=1
12000 ! 桁処理2 --桁上げ処理
DO
LET OBF=0
for I= KTA TO 1
step -1
LET XN1(I-1)=XN1(I-1)+int(XN1(I)/10^100)
LET
XN1(I)=XN1(I)-10^100*int(XN1(I)/10^100)
if XN1(I)>10^100 then
LET
OBF=1
end if
NEXT I
loop while OBF=1
13000 ! XN1 => XN0
へ入替
for I=0 to KTA
LET XN0(I)=XN1(I)
NEXT I
!2回目以降の初期化
2回目以降の初期化2回目以降の初期化2回目以降の初期化2回目以降の初期化2回目以降の初期化
for I=0 To KTA
! XN0(I)=0
2回目の初期化では『0』にしない。
LET XN1(I)=0
LET XN02(I)=0
! LET AXN02(I)=0
LET
AXN02m3(I)=0
LET AXN02m3X(I)=0
next I
return
20000 !初期設定
初期設定 初期設定 初期設定 初期設定 初期設定 初期設定 初期設定 初期設定 初期設定
for I=0 To KTA
LET
A(I)=0
LET XN0(I)=0
LET XN1(I)=0
LET XN02(I)=0
! LET
AXN02(I)=0
LET AXN02m3(I)=0
LET AXN02m3X(I)=0
LET OPT5(I)=0
next
I
LET XN0(0)=int(1/sqr(3)) ! 1/√3≒0.577
LET
XN0(1)=int((1/sqr(3)-int(1/sqr(3)))*1000000)*10^(100-6)
LET A(0)=1
LET
OPT5(0)=1 ! 1.5
LET OPT5(1)=5*10^99 !
1.5
return
END