UBASICのビット演算関数の実装

 投稿者:山中和義  投稿日:2008年12月29日(月)19時42分22秒
 
!真理値表
LET a=3 !0011のパターン
LET b=5 !0101のパターン

PRINT " b NOT" !否定
FOR i=0 TO 1
   PRINT bit(i,b); 1-bit(i,b) !b'=1-b
NEXT i
PRINT " a  b IMP" !論理包含
FOR i=0 TO 3
   PRINT bit(i,a); bit(i,b); bit(i,bitor(bitreverse(i,a),b)) !a' or b
NEXT i
PRINT " a  b EQV" !同値
FOR i=0 TO 3
   PRINT bit(i,a); bit(i,b); 1-bit(i,bitxor(a,b)) !(a xor b)'
NEXT i



!2の補数:定義より
LET n=16 !nビット符号付整数 -2^(n-1)~2^(n-1)-1
LET m=2^n

LET a=3
LET aa=m-a !a+a'=m
FOR i=N-1 TO 0 STEP -1 !上の位から
   PRINT bit(i,aa);
NEXT i
PRINT


!2の補数:反転して1をたす
LET a=3
FOR i=N-1 TO 0 STEP -1 !上の位から
   LET a=bitreverse(i,a)
NEXT i
LET a=a+1
PRINT a !nビット符号なし整数 0~2^n-1

!2の補数:反転して1をたす ※別解
LET a=3
FOR i=0 TO N-1 !下の位から
   IF bit(i,a)=1 THEN EXIT FOR !1が見つかるまで
   LET a=bitreset(i,a) !0にする
NEXT i
FOR k=i+1 TO N-1 !続き
   LET a=bitreverse(k,a) !0を1にする
NEXT k
PRINT a



!加算 a+b
LET a=123
LET b=45
DO WHILE bitand(a,b)>0
   LET t=bitxor(a,b)
   LET b=sft(bitand(a,b),1)
   LET a=t
LOOP
PRINT bitxor(a,b)


END


!ビット演算関連 ※UBASICより

EXTERNAL FUNCTION bit(n,x) !n番目のビット値 ※n,xは整数
IF n<>INT(n) OR x<>INT(x) THEN !整数以外なら
   PRINT "パラメータが不適当です。"
   STOP
ELSE
   LET bit=MOD(INT(x/2^n),2)
END IF
END FUNCTION

EXTERNAL FUNCTION bitset(n,x) !n番目のビットを1にする ※n,xは非負整数
IF n<0 OR n<>INT(n) OR x<0 OR x<>INT(x) THEN !非負整数以外なら
   PRINT "パラメータが不適当です。"
   STOP
ELSE
   LET d=2^n !n桁
   LET bitset=(INT(x/d/2)*2+1)*d+MOD(x,d) !大きい桁+1+小さい桁
END IF
END FUNCTION

EXTERNAL FUNCTION bitreset(n,x) !n番目のビットを0にする ※n,xは非負整数
IF n<0 OR n<>INT(n) OR x<0 OR x<>INT(x) THEN !非負整数以外なら
   PRINT "パラメータが不適当です。"
   STOP
ELSE
   LET d=2^n !n桁
   LET bitreset=INT(x/d/2)*2*d+MOD(x,d) !大きい桁+1+小さい桁
END IF
END FUNCTION

EXTERNAL FUNCTION bitreverse(n,x) !n番目のビットを反転する ※n,xは非負整数
IF n<0 OR n<>INT(n) OR x<0 OR x<>INT(x) THEN !非負整数以外なら
   PRINT "パラメータが不適当です。"
   STOP
ELSE
   LET d=2^n !n桁
   LET a=INT(x/d)
   LET bitreverse=(INT(a/2)*4-a+1)*d+MOD(x,d) !大きい桁+NOT+小さい桁
END IF
END FUNCTION

EXTERNAL FUNCTION bitand(a,b) !ビットごとの論理積 ※a,bは非負整数
IF a<0 OR a<>INT(a) OR b<0 OR b<>INT(b) THEN !非負整数以外なら
   PRINT "パラメータが不適当です。"
   STOP
ELSE
   LET c=0 !値
   LET d=1
   DO UNTIL a=0 OR b=0 !最下位の桁から、桁数が小さい方まで
      LET aa=INT(a/2)
      LET bb=INT(b/2)
      LET c=c + MIN((a-aa*2),(b-bb*2)) * d !and(x,y)=MIN(x,y)

      LET a=aa !次へ
      LET b=bb
      LET d=d*2
   LOOP
   LET bitand=c
END IF
END FUNCTION

EXTERNAL FUNCTION bitor(a,b) !ビットごとの論理和 ※a,bは非負整数
IF a<0 OR a<>INT(a) OR b<0 OR b<>INT(b) THEN !非負整数以外なら
   PRINT "パラメータが不適当です。"
   STOP
ELSE
   LET c=0
   LET d=1
   DO UNTIL a=0 AND b=0 !桁数が大きい方
      LET aa=INT(a/2)
      LET bb=INT(b/2)
      LET c=c+MAX((a-aa*2),(b-bb*2)) * d !or(x,y)=MAX(x,y)
      LET a=aa !次へ
      LET b=bb
      LET d=d*2
   LOOP
   LET bitor=c
END IF
END FUNCTION

EXTERNAL FUNCTION bitxor(a,b) !ビットごとの排他的論理和 ※a,bは非負整数
IF a<0 OR a<>INT(a) OR b<0 OR b<>INT(b) THEN !非負整数以外なら
   PRINT "パラメータが不適当です。"
   STOP
ELSE
   LET c=0
   LET d=1
   DO UNTIL a=0 AND b=0 !桁数が大きい方
      LET aa=INT(a/2)
      LET bb=INT(b/2)
      LET c=c + MOD((a-aa*2)+(b-bb*2),2) * d !xor(x,y)=MOD(x+y,2)
      LET a=aa !次へ
      LET b=bb
      LET d=d*2
   LOOP
   LET bitxor=c
END IF
END FUNCTION

EXTERNAL FUNCTION bitcount(x) !1であるビットの個数 ※xは非負整数
IF x<0 OR x<>INT(x) THEN !非負整数以外なら
   PRINT "パラメータが不適当です。"
   STOP
ELSE
   LET c=0 !値
   DO UNTIL x=0 !最下位の桁から
      LET xx=INT(x/2) !商
      LET c=c + (x-xx*2) !余り

      LET x=xx !次へ
   LOOP
   LET bitcount=c
END IF
END FUNCTION

EXTERNAL FUNCTION sft(x,n) !nビットのシフトする ※nは整数
IF n<>INT(n) THEN !整数以外なら
   PRINT "パラメータが不適当です。"
   STOP
ELSE
   IF n<0 THEN LET d=1/2 ELSE LET d=2
   FOR i=1 TO ABS(n)
      LET x=x*d
   NEXT i
   LET sft=x
END IF
END FUNCTION
 

戻る