十進モードでの計算の不具合

 投稿者:山中和義  投稿日:2010年 3月29日(月)16時09分21秒
  下記の「ビット列の並びを反転する」プログラムのビット演算を行うと
十進モードでは、他のモード(1000桁、2進、有理数)と計算結果が異なります。
LET m=4
LET N=2^m

FOR i=0 TO N-1

   LET x=i
   LET x=bitor( sft(bitand(x,BVAL("AAAAAAAA",16)),-1), sft(bitand(x,BVAL("55555555",16)),1) )
   LET x=bitor( sft(bitand(x,BVAL("CCCCCCCC",16)),-2), sft(bitand(x,BVAL("33333333",16)),2) )
   LET x=bitor( sft(bitand(x,BVAL("F0F0F0F0",16)),-4), sft(bitand(x,BVAL("0F0F0F0F",16)),4) )
   LET x=bitor( sft(bitand(x,BVAL("FF00FF00",16)),-8), sft(bitand(x,BVAL("00FF00FF",16)),8) )
   LET x=bitor(sft(x,-16),sft(x,16)) !FFFF0000,0000FFFF
   LET x=sft(x,-(32-m))

   PRINT i;BSTR$(i,2),
   IF x<0 THEN PRINT 2^m+x;BSTR$(2^m+x,2) ELSE PRINT x;BSTR$(x,2)

NEXT i

END

EXTERNAL FUNCTION bitand(a,b) !ビットごとの論理積
LET c=0 !値
FOR i=0 TO 31
   LET aa=MOD(a,2)
   LET a=(a-aa)/2
   LET bb=MOD(b,2)
   LET b=(b-bb)/2
   LET c=c+MIN(aa,bb)*2^i
NEXT i
IF c>=2^31 THEN LET c=c-2^32
LET bitand=c
END FUNCTION

EXTERNAL FUNCTION bitor(a,b) !ビットごとの論理和
LET c=0
FOR i=0 TO 31
   LET aa=MOD(a,2)
   LET a=(a-aa)/2
   LET bb=MOD(b,2)
   LET b=(b-bb)/2
   LET c=c+MAX(aa,bb)*2^i
NEXT i
IF c>=2^31 THEN LET c=c-2^32
LET bitor=c
END FUNCTION

EXTERNAL FUNCTION sft(x,n) !nビットのシフトする ※nは整数
LET sft=IP(x*2^n)
END FUNCTION
 

Re: 十進モードでの計算の不具合

 投稿者:白石 和夫  投稿日:2010年 3月29日(月)17時06分14秒
  > No.1123[元記事へ]

トレース出力が最初に一致しない部分をプログラムにすると

LET N=-28
LET X=-2147483648
LET sft=IP(x*2^n)
PRINT sft
END

となります。
その結果は,十進モードで-7,1000桁モードで-8となります。
理由は,2^(-28)の正しい値は
(1000桁モードの計算で)
.0000000037252902984619140625
ですが,十進モードでは,
.000000003725290298461914
に丸められるのが原因です。
 

Re: 十進モードでの計算の不具合

 投稿者:山中和義  投稿日:2010年 3月29日(月)21時17分20秒
  > No.1124[元記事へ]

白石 和夫さんへのお返事です。

> 丸められるのが原因です。

次のように変更して対応します。
EXTERNAL FUNCTION sft(x,n) !nビットのシフトする ※nは整数
LET t=x*2^n
LET sft=IP(t)
!!!丸めによる結果が期待にそわない LET sft=IP(x*2^n)
END FUNCTION

または
EXTERNAL FUNCTION sft(x,n) !nビットのシフトする ※nは整数
IF n>=0 THEN
   LET sft=x*2^n
ELSE
   LET sft=IP(x/2^(-n)) !※丸めにより期待にそわない LET sft=IP(x*2^n)
END IF
END FUNCTION
 

戻る