つづき
FUNCTION frac2dec$(m,n,RADIX) !10進法分数(m/n)を(RADIX)進数で小数表示するときの文字列に変換する
IF SGN(m)*SGN(n)<0 THEN LET cSGN$="-" ELSE LET cSGN$="" !符号を得る
LET aa=ABS(m)
LET b=ABS(n)
LET t=GCD(aa,b) !最大公約数で分子と分母を約分する
LET aa=aa/t
LET b=b/t
!!!PRINT aa;b;t !debug
!整数部
LET a=INT(aa/b) !小数部を削除する
LET b$="" !変換後の数
DO WHILE a>=RADIX !a=b[k]*RADIX^k+b[k-1]*RADIX^(k-1)+ … +b[1]*RADIX^1+b[0]*RADIX^0より
LET b$=STR1$(MOD(a,RADIX))&b$ !一の位から求まる
LET a=INT(a/RADIX) !次の桁へ ※右シフト
LOOP
LET b$=STR1$(a)&b$
!小数部
LET aa=MOD(aa,b) !整数部を削除する
LET k=0 !小数部の桁数
DO UNTIL aa=0 !小数第1位から順に
LET k=k+1
IF k>MIN(b,Precision) THEN !循環小数によるループを回避する
PRINT "変換を打ち切りました。"
EXIT DO
END IF
IF k=1 THEN !初回のみ
LET b$=b$&"." !小数点をつける
LET p=LEN(b$) !位置を記録しておく
ELSE
FOR i=1 TO k-1 !循環したかどうか確認する
IF s(i)=aa THEN EXIT DO !循環節なら、終了!
NEXT i
END IF
LET s(k)=aa !小数第k位以降(未展開の小数部)の数を記録する
LET aa=aa*RADIX !左シフトして、商を求める
LET a=INT(aa/b)
LET b$=b$&STR1$(a) !a=S[-1]*RADIX^(-1)+S[-2]*RADIX^(-2)+ … +S[-(k-1)]*RADIX^(-(k-1))+S[-k]*RADIX^(-k)より
LET aa=MOD(aa,b) !剰余を求めて、次の桁へ
LOOP
IF aa=0 THEN !有限小数(整数も含む)なら
LET p=k !有限小数の桁数
LET k=0 !循環節の桁数
ELSE !循環小数なら
LET b$(i+p:i+p)="["&b$(i+p:i+p) !開始記号を挿入
LET b$=b$&"]" !終了記号
LET p=i-1 !有限小数の桁数
LET k=k-i !循環節の桁数
END IF
LET frac2dec$=cSGN$&b$ !-9.9[9] 形式
END FUNCTION
!------------------------------ ここまでがサブルーチン
!● 0.[13](4)を10進法の分数で表現する 答え 7/15
!※等比数列の和 初項 0.13(4)=1/4^1+3/4^2、公比 0.01(4)=1/4^2
! LET a = 0. + (1/4^1+3/4^2)/(1-1/4^2)
! PRINT a
PRINT ExBVAL("0.[13]",4)
!● 1/7を3進法の小数(循環する)で表現する 答え 0.[010212](3)
PRINT ExBSTR$(1/7,3)
!● 0.1[23] ÷ 0.[14] の結果を循環小数で表せ。 答え 0.8[714285]
!筆算
! x=0.1[23]とすると
! 100*x-x=12.3[23]-0.1[23]=12.2 ∴99*x=122/10 ∴x=61/495
LET t=ExVAL("0.1[23]") / ExVAL("0.[14]")
PRINT t, ExSTR$(t)
!● 3/7 を小数で表したとき、小数第800位の数字を求めよ。 答え 2
LET x$=ExSTR$(3/7) !0.[428571]
LET y$=x$(POS(x$,"[")+1:POS(x$,"]")-1) !循環節を切り出す
LET x=MOD(800,LEN(y$)) !800/6=133 余り 2
PRINT y$(x:x)
END
10進15桁モードの場合
先頭の OPTION ARITHMETIC RATIONAL をコメントアウトして、
計算部分のプログラムは以下のものに置き換えて、(小数⇔分数のルーチンを直接呼び出す)
10進15桁モードで実行します。
!● 0.[13](4)を10進法の分数で表現する 答え 7/15
!※等比数列の和 初項 0.13(4)=1/4^1+3/4^2、公比 0.01(4)=1/4^2
! LET a = 0. + (1/4^1+3/4^2)/(1-1/4^2)
! PRINT a
CALL dec2frac("0.[13]",4, m,n) !小数を分数へ
PRINT m;"/";n
!● 1/7を3進法の小数(循環する)で表現する 答え 0.[010212](3)
PRINT frac2dec$(1,7, 3) !分数を小数へ
!● 0.1[23] ÷ 0.[14] の結果を循環小数で表せ。 答え 0.8[714285]
!筆算
! x=0.1[23]とすると
! 100*x-x=12.3[23]-0.1[23]=12.2 ∴99*x=122/10 ∴x=61/495
CALL dec2frac("0.1[23]",10, m,n)
CALL dec2frac("0.[14]",10, x,y)
PRINT frac2dec$(m*y,n*x,10) !(m/n)÷(x/y)=(m*y)÷(n*x)
!● 3/7 を小数で表したとき、小数第800位の数字を求めよ。 答え 2
LET x$=frac2dec$(3,7,10)
LET y$=x$(POS(x$,"[")+1:POS(x$,"]")-1) !循環節を切り出す
LET x=MOD(800,LEN(y$)) !800/6=133 余り 2
PRINT y$(x:x)