バグ?INT関数

 投稿者:山中和義  投稿日:2009年 8月23日(日)19時12分28秒
  10進モードと2進モードで値が異なります。
これらは有効桁数による計算誤差でしょうか?
!LET p=10 !例1
!LET n=1000
!LET p=5 !例2
!LET n=625
LET p=7 !例3
LET n=49
LET x1=LOG(n)/LOG(p) !整数部分が異なる
LET x2=INT(LOG(n)/LOG(p)) !
PRINT x1; x2; INT(x1)
END
 

Re: バグ?INT関数

 投稿者:荒田浩二  投稿日:2009年 8月24日(月)07時37分8秒
  > No.492[元記事へ]

下のプログラムを[オプション][数値][表示桁数を多く]にチェックをいれて実行してみてください。

ヘルプの[操作][オプションメニュー][数値]によると、実際に計算される数値と表示される数値の精度に違いがあるようです。
例1では、2進モードでx1は19桁目までは 2.999999999999999555 の値を持ちますが通常表示では15桁に丸められ 3 と表示されます。
例2例3は「10進15桁モードでは数値式とその値を代入した変数とでは精度が異なる」ことに起因すると思われます。
たとえば次の小プログラムでも、10進モードでは a/7 と b は異なる値になります。
   10 LET a=1
   20 LET b=a/7
   30 PRINT a/7 ; b
   40 END


OPTION ARITHMETIC DECIMAL
!LET p=10 !例1
!LET n=1000
!LET p=5 !例2
!LET n=625
LET p=7 !例3
LET n=49
LET x1=LOG(n)/LOG(p) !整数部分が異なる
LET x2=INT(LOG(n)/LOG(p)) !
PRINT "LOG(n)/LOG(p) =";LOG(n)/LOG(p)
PRINT "x1 =";x1
PRINT "INT(LOG(n)/LOG(p)) =";INT(LOG(n)/LOG(p))
PRINT "INT(x1) =";INT(x1)
PRINT "x2 =";x2
PRINT
CALL binary(STR$(p),STR$(n))
PRINT
CALL thousand(STR$(p),STR$(n))
END

EXTERNAL SUB binary(p$,n$)
OPTION ARITHMETIC NATIVE
LET p=VAL(p$)
LET n=VAL(n$)
LET x1=LOG(n)/LOG(p) !整数部分が異なる
LET x2=INT(LOG(n)/LOG(p)) !
PRINT "LOG(n)/LOG(p) =";LOG(n)/LOG(p)
PRINT "x1 =";x1
PRINT "INT(LOG(n)/LOG(p)) =";INT(LOG(n)/LOG(p))
PRINT "INT(x1) =";INT(x1)
PRINT "x2 =";x2
END SUB

EXTERNAL SUB thousand(p$,n$)
OPTION ARITHMETIC DECIMAL_HIGH
LET p=VAL(p$)
LET n=VAL(n$)
LET x1=LOG(n)/LOG(p) !整数部分が異なる
LET x2=INT(LOG(n)/LOG(p)) !
PRINT "LOG(n)/LOG(p) =";LOG(n)/LOG(p)
PRINT "x1 =";x1
PRINT "INT(LOG(n)/LOG(p)) =";INT(LOG(n)/LOG(p))
PRINT "INT(x1) =";INT(x1)
PRINT "x2 =";x2
END SUB
 

Re: バグ?INT関数

 投稿者:山中和義  投稿日:2009年 8月24日(月)13時42分56秒
  > No.493[元記事へ]

自然数nのp進法表記での桁数を求めるプログラムをつくるときに気づきました。
思わぬ落とし穴です。直接、進数変換して桁数を求めることにします。
ありがとうございます。
LET STR1$="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" !p進法の数字
FUNCTION ExBSTR$(n,p) !非負の整数nをp進法で表記する
   LET s$=""
   DO
      LET nn=INT(n/p)
      LET t=n-nn*p !MOD(n,p)
      LET s$=STR1$(t+1:t+1)&s$ !下の位から
      LET n=nn
   LOOP UNTIL n=0
   LET ExBSTR$=s$
END FUNCTION


LET p=5 !進数

FOR n=1 TO p^p !自然数

   LET x=INT(LOG(n)/LOG(p))+1 !桁数
   LET x2=INT(LOG2(n)/LOG2(p))+1
   LET x10=INT(LOG10(n)/LOG10(p))+1
   LET k=g(n,p) !進数変換による
   IF k<>x OR k<>x2 OR k<>x10 THEN PRINT n; STR$(p);"#";ExBSTR$(n,p), k; x; x2; x10

NEXT n


FUNCTION g(n,p) !自然数nのp進法での桁数 ※p^c=n
   LET t=1
   LET c=0 !桁数
   DO
      LET t=t*p
      LET c=c+1
   LOOP WHILE t<=n
   LET g=c
END FUNCTION

END
 

戻る