スクリプト/ビット演算関数(履歴ID:723)
最終投稿者: shainy
更新:2018/10/06 15:18:57
概要
ビット演算関数は数値を10進数ではなく、符号付き32ビット整数を2進表現したものとして扱います。例えば、10進数の10は00000000000000000000000000001010です。ビット演算関数はこのように2進表現にした上で演算を行いますが、標準のArrpの数値を返します。
使用できる関数には次のものがあります。
演算関数 | 記述例 | 説明 |
---|---|---|
ビットAND | bitwiseAND(a, b) | 対応するビットがともに1である各ビットについて1を返します。 |
ビットOR | bitwiseOR(a, b) | 対応するビットがどちらかまたはともに1である各ビットについて1を返します。 |
ビットXOR | bitwiseXOR(a, b) | 対応するビットがどちらか一方のみ1である各ビットについて1を返します。 |
ビットNOT | bitwiseNOT(value) | 各ビットを反転します。 |
左シフト | leftShift(a, b) | 2進表現のaをbビット分だけ左にシフトします。 |
右シフト | rightShift(a, b) | 2進表現のaをbビット分だけ右にシフトします。 |
0埋め右シフト | rightShiftZeroFill(a, b) | 2進表現のaをbビット分だけ右にシフトします。 |
目次
導入方法
ビット演算関数は標準のArrpでは使うことができません。あなたのゲームに導入するには、以下のソースコードをコピーしてあなたのスクリプトに貼り付けてください。複数のシーンやマップで使いたい場合は開始スクリプトで行ってください。また上記の関数の他に_binaryBitwiseNOT,_toBinary,_toInteger,_toUnsignedIntegerの4つを関数名として使用しています。
以下ソースコード。
def _binaryBitwiseNOT(value) index=0 while index<32 do value[index]=(!value[index]) index=index+1 end end def _toBinary(value) value=floor(value) isMinus=value<0 if isMinus then value=-value end binary=createArray() index=0 while value>0 do binary[index]=((value%2)==1) value=floor(value/2) index=index+1 end while index<32 do binary[index]=false index=index+1 end if isMinus then _binaryBitwiseNOT(binary) index=0 while index==0||((!binary[index-1])&&index<32) do binary[index]=(!binary[index]) index=index+1 end end return binary end def _toInteger(value) number=0 index=0 if value[31] then _binaryBitwiseNOT(value) while index==0||((!value[index-1])&&index<32) do value[index]=(!value[index]) index=index+1 end base=-1 index=0 else base=1 end while index<32 do if value[index] then number=number+base end base=base*2 index=index+1 end return number end def _toUnsignedInteger(value) number=0 index=0 base=1 while index<32 do if value[index] then number=number+base end base=base*2 index=index+1 end return number end def bitwiseAND(left,right) leftBinary=_toBinary(left) rightBinary=_toBinary(right) index=0 while index<32 do leftBinary[index]=(leftBinary[index]&&rightBinary[index]) index=index+1 end return _toInteger(leftBinary) end def bitwiseOR(left,right) leftBinary=_toBinary(left) rightBinary=_toBinary(right) index=0 while index<32 do leftBinary[index]=(leftBinary[index]||rightBinary[index]) index=index+1 end return _toInteger(leftBinary) end def bitwiseXOR(left,right) leftBinary=_toBinary(left) rightBinary=_toBinary(right) index=0 while index<32 do leftBinary[index]=(leftBinary[index]||rightBinary[index])&&(!(leftBinary[index]&&rightBinary[index])) index=index+1 end return _toInteger(leftBinary) end def bitwiseNOT(value) binary=_toBinary(value) _binaryBitwiseNOT(binary) return _toInteger(binary) end def leftShift(value,bit) binary=_toBinary(value) newBinary=createArray() index=0 while index<32 do from=index-((32+bit)%32) newBinary[index]=(from>=0)&&binary[from] index=index+1 end return _toInteger(newBinary) end def rightShift(value,bit) binary=_toBinary(value) newBinary=createArray() index=31 while index>=0 do from=index+((32+bit)%32) if from<32 then newBinary[index]=binary[from] else newBinary[index]=binary[31] end index=index-1 end return _toInteger(newBinary) end def rightShiftZeroFill(value,bit) binary=_toBinary(value) newBinary=createArray() index=31 while index>=0 do from=index+((32+bit)%32) if from<32 then newBinary[index]=binary[from] else newBinary[index]=false#binary[31] end index=index-1 end return _toUnsignedInteger(newBinary) end
ビット演算関数
ビットAND(bitwiseAND関数)
ゲームタイプ | 利用 |
---|---|
2DアクションRPG | Yes |
2DRPG | Yes |
ノベルゲーム | Yes |
同じ位置のビットを比較してどちらも1の場合だけ1に、それ以外は0にします。
and = bitwiseAND(a, b)
- 第1引数は演算する整数
- 第2引数は演算する整数
- 返り値は第1引数と第2引数のビットAND
11と14のビットANDは10が返ります。
and = bitwiseAND(11, 14) speak(and) #10
11と14を2進表現にします。各ビットを比較し両方が1の場合は1に、それ以外(1と0、0と0など)の場合は0にします。その結果2進数の1000となり、10進数の10が返ります。
0000 0000 0000 0000 0000 0000 0000 1011 = 11 0000 0000 0000 0000 0000 0000 0000 1110 = 14 ---- ---- ---- ---- ---- ---- ---- ---- -- 0000 0000 0000 0000 0000 0000 0000 1010 = 10
ビットOR(bitwiseOR関数)
ゲームタイプ | 利用 |
---|---|
2DアクションRPG | Yes |
2DRPG | Yes |
ノベルゲーム | Yes |
同じ位置のビットを比較してどちらかが1の場合は1に、どちらも0の場合は0にします。
or = bitwiseOR(a, b)
- 第1引数は演算する整数
- 第2引数は演算する整数
- 返り値は第1引数と第2引数のビットOR
10と12のビットORは14が返ります。
or = bitwiseOR(10, 12) speak(or) #14
10と12を2進表現にします。各ビットを比較しどちらかが1の場合(どちらも1の場合も含む)は1に、どちらも0の場合は0にします。その結果2進数の1110となり、10進数の14が返ります。
0000 0000 0000 0000 0000 0000 0000 1010 = 10 0000 0000 0000 0000 0000 0000 0000 1100 = 12 ---- ---- ---- ---- ---- ---- ---- ---- -- 0000 0000 0000 0000 0000 0000 0000 1110 = 14
ビットXOR(bitwiseXOR関数)
ゲームタイプ | 利用 |
---|---|
2DアクションRPG | Yes |
2DRPG | Yes |
ノベルゲーム | Yes |
同じ位置のビットを比較してどちらか一方だけが1の場合は1に、それ以外は0にします。
xor = bitwiseXOR(a, b)
- 第1引数は演算する整数
- 第2引数は演算する整数
- 返り値は第1引数と第2引数のビットXOR
10と12のビットXORは6が返ります。
xor = bitwiseXOR(10, 12) speak(xor) #6
10と12を2進表現にします。各ビットを比較しどちらか一方だけが1の場合は1に、それ以外は0にします。ビットORとは異なり、1と1の場合は0になります。その結果2進数の110となり、10進数の6が返ります。
0000 0000 0000 0000 0000 0000 0000 1010 = 10 0000 0000 0000 0000 0000 0000 0000 1100 = 12 ---- ---- ---- ---- ---- ---- ---- ---- -- 0000 0000 0000 0000 0000 0000 0000 0110 = 6
ビットNOT(bitwiseNOT関数)
ゲームタイプ | 利用 |
---|---|
2DアクションRPG | Yes |
2DRPG | Yes |
ノベルゲーム | Yes |
ビットを反転します。
not = bitwiseNOT(value)
- 第1引数は演算する整数
- 返り値は第1引数のビットNOT
10のビットNOTは-11が返ります。
not = bitwiseNOT(10) speak(not) #-11
10を2進表現にします。各ビットを0の場合は1に、1の場合は0にします。その結果2進数の11111111111111111111111111110101となり、10進数の-11が返ります。
0000 0000 0000 0000 0000 0000 0000 1010 = 10 ---- ---- ---- ---- ---- ---- ---- ---- --- 1111 1111 1111 1111 1111 1111 1111 0101 = -11
左シフト(leftShift関数)
ゲームタイプ | 利用 |
---|---|
2DアクションRPG | Yes |
2DRPG | Yes |
ノベルゲーム | Yes |
指定したビット分だけ左にシフトします。
leftshift = leftShift(a, b)
- 第1引数は演算する整数
- 第2引数はシフトするビット数
- 返り値は第1引数を第2引数分だけ左にシフトした結果
10を1ビット左にシフトすると20が返ります。
leftshift = leftShift(10, 1) speak(leftshift) #20
10を2進表現にします。各ビットを1ビット分だけ左へシフトします。左端からはみ出した部分は削除され、シフトしたことによって空いた右端は0で詰められます。その結果2進数の10100となり、10進数の20が返ります。
0000 0000 0000 0000 0000 0000 0000 1010 = 10 ---- ---- ---- ---- ---- ---- ---- ---- -- 0000 0000 0000 0000 0000 0000 0001 0100 = 20
右シフト(rightShift関数)
ゲームタイプ | 利用 |
---|---|
2DアクションRPG | Yes |
2DRPG | Yes |
ノベルゲーム | Yes |
指定したビット分だけ右にシフトします。
rightshift = rightShift(a, b)
- 第1引数は演算する整数
- 第2引数はシフトするビット数
- 返り値は第1引数を第2引数分だけ右にシフトした結果
10を1ビット右にシフトすると5が返ります。
rightshift = rightShift(10, 1) speak(rightshift) #5
10を2進表現にします。各ビットを1ビット分だけ右へシフトします。右端からはみ出した部分は削除され、シフトしたことによって空いた左端は、元々の値が1だった場合は1、0だった場合は0が格納されます。その結果2進数の101となり、10進数の5が返ります。
0000 0000 0000 0000 0000 0000 0000 1010 = 10 ---- ---- ---- ---- ---- ---- ---- ---- -- 0000 0000 0000 0000 0000 0000 0000 0101 = 5
0埋め右シフト(rightShiftZeroFill関数)
ゲームタイプ | 利用 |
---|---|
2DアクションRPG | Yes |
2DRPG | Yes |
ノベルゲーム | Yes |
指定したビット分だけ右にシフトします。
rightshiftzerofill = rightShiftZeroFill(a, b)
- 第1引数は演算する整数
- 第2引数はシフトするビット数
- 返り値は第1引数を第2引数分だけ右にシフトした結果
10を1ビット右にシフトすると5が返ります。
rightshiftzerofill = rightShiftZeroFill(10, 1) speak(rightshiftzerofill) #5
10を2進表現にします。各ビットを1ビット分だけ右へシフトします。右端からはみ出した部分は削除され、シフトしたことによって空いた左端は、0が格納されます。その結果2進数の101となり、10進数の5が返ります。
0000 0000 0000 0000 0000 0000 0000 1010 = 10 ---- ---- ---- ---- ---- ---- ---- ---- -- 0000 0000 0000 0000 0000 0000 0000 0101 = 5