自作クラスを作らずにVBAでビット列操作をするためには通常 Long型 (4 byte) を使用する。ただし、Long型の32bitのうち、1bitは符号ビットなので、実質簡単に使えるのは31bitなのだ。
そこで、「bを使用ビット数」とする「ビット反転関数 bturn」は次のようになるかね。
function bturn(x as Long, b as Integer) as Long 'x : 反転させたい値 'b : 使うビット数(桁数) bturn = x Xor (2 ^ b -1) End Function
VBAでは次のようなビット列演算子が使用できる。それぞれの意味を特に説明する必要は無いだろう。
使用例
Dim a as Long Dim b as Long Dim c as Long a = 2^0 '0 0000000000000000000000000000001 = 1 b = 2^1 '0 0000000000000000000000000000010 = 2 c = a Xor b '0 0000000000000000000000000000011 = 3
気づくと思うけど、ビット反転に相当する「Not」が無い。そこで「ビット反転」をするには、関数を自作する必要があるのです。ここで上記演算子を使ってビット反転するにはどうするか考える。まず、それぞれを論理式で書いてみる。(飛ばしても良い)
- And :
- Or :
- Xor :
- Eqv :
- Imp :
ここでBをTrueとして考えると次のようになる。
- And :
- Or :
- Xor :
- Eqv :
- Imp :
※ EqvとImpは最終的にになると、「Not A」と評価されるようす。つまり使えないか、使うとめんどくさいことになりそう。
つまりXorを使えば、、Aのビット反転が作れます。
なので、マスクビット(希望するビット数だけTになる値)を用意してXorで反転させればAの希望ビット数のビット反転が手に入るということになります。
ってことで、希望する使用ビット数をまず考えます。ここでは境界問題を包含するために、31 bit より小さい16 bitにしましょう。16 bit のマスク = 16 bit全てが1となります。は二進数で「10000000000000000」(桁数17)です。そこから1を引くと、「01111111111111111」となります。これで16 bit全てが1になる数字が作れますね。
で結果、「nを使用ビット数」とする「ビット反転関数 bturn」は次のようになるかなぁ。
function bturn(x as Long, b as Integer) as Long 'x : 反転させたい値 'b : 使うビット数(桁数) bturn = x Xor (2 ^ b -1) End Function