ビット演算子

And, Or, Xor, Notの各演算子は、整数型に対してはビット演算子として動作します。 Andはビットごとの論理積、Orは論理和、Xorは排他的論理和、Notは論理否定となります。

Dim i As Integer

i = 8 Or 5                    ' 論理和       : i = &H0000000D
i = &H12345678 And &HFF0000FF ' 論理積       : i = &H12000078
i = &H00FF00FF Xor &H0000FFFF ' 排他的論理和 : i = &H00FFFF00
i = Not &H00FF00FF            ' 論理否定     : i = &HFF00FF00

例えば、変数の特定ビットが立っているかを調べるにはAnd演算子を使って次のようにします。

Dim b As Byte = &HAA ' = 0b10101010

If b And &H1 Then Console.WriteLine("1ビット目") ' &H1 = 0b00000001
If b And &H2 Then Console.WriteLine("2ビット目") ' &H2 = 0b00000010
If b And &H4 Then Console.WriteLine("3ビット目") ' &H4 = 0b00000100
If b And &H8 Then Console.WriteLine("4ビット目") ' &H8 = 0b00001000
実行結果
2ビット目
4ビット目

AndAlso演算子・OrElse演算子をビット演算子として使用することはできません。 常に論理演算子として機能します。

Long型を使うことで最大64ビットの数値を扱うことができますが、それよりも長大なビット値を操作するにはBigInteger型やコレクションの一種であるBitArrayクラスを使用することもできます。

列挙体とビット演算

ビット演算子は列挙体にも使えます。 FileAttributes列挙体などビットごとの組み合わせが可能な列挙体に対して使用することで、値を組み合わせたり、特定の値がセットされているかどうかを調べることができます。

Dim attr As FileAttributes

' 読み取り専用でシフテムファイルを表すファイル属性
attr = FileAttributes.ReadOnly Or FileAttributes.System

' ファイルに設定されている属性を取得する
attr = File.GetAttributes("E:\test.txt")

' 属性にFileAttributes.ReadOnlyがセットされているか調べる
If (attr And FileAttributes.ReadOnly) = FileAttributes.ReadOnly Then
  Console.WriteLine("ファイルは読み取り専用です")
End If
' CTRL+ALT+DELETEを表すキーコード
Dim key As Keys = Keys.Control Or Keys.Alt Or Keys.Delete

' And演算でビットマスクをとって修飾キーコードと仮想キーコードを分離する
Dim virtKey As Keys = key And Keys.KeyCode
Dim modifiers As Keys = key And Keys.Modifiers

列挙体とビットごとの組み合わせについては列挙体とフラグでも解説しています。

ビット表記

次の例のように値を十六進数で記述したり、十六進数・二進数形式で文字列化したりする方法についてはリテラルとサフィックスで解説しています。

十六進数・二進数表記で文字列化する例
Dim bitsOr As Integer = 8 Or 5
Dim bitsAnd As Integer = &H12345678 And &HFF0000FF
Dim bitsXor As Integer = &H00FF00FF Xor &H0000FFFF
Dim bitsNot As Integer = Not &H00FF00FF

Console.WriteLine("{0} {1}", bitsOr.ToString("X8"),  Convert.ToString(bitsOr, 2))
Console.WriteLine("{0} {1}", bitsAnd.ToString("X8"), Convert.ToString(bitsAnd, 2))
Console.WriteLine("{0} {1}", bitsXor.ToString("X8"), Convert.ToString(bitsXor, 2))
Console.WriteLine("{0} {1}", bitsNot.ToString("X8"), Convert.ToString(bitsNot, 2))
実行結果
0000000D 1101
12000078 10010000000000000000001111000
00FFFF00 111111111111111100000000
FF00FF00 11111111000000001111111100000000

ビットシフト演算子

VB7.1(VB2003)以降ではビットシフト演算子を使用することができます。 ビットシフト演算子はその名の通り、値のビット表記に対してその表記を右または左にシフトする演算子です。 >>演算子は算術右シフト、<<演算子は算術左シフトを行います。

ビットシフト演算子は「値または変数 >> 右シフトの量」もしくは「値または変数 << 左シフトの量」のように使用します。 算術的には、nビット右にシフトすることは値を2nで割ることと等しく、nビット左にシフトすることは値に2nを掛けることと等しい演算です。

なお、ビットシフト演算子はその特性上、整数型(Byte, Integer, UInteger, Longなど)に対してのみ使用できます。

Dim i As Integer

i = 4 >> 1 ' 算術右シフト : i = 4 \ (2 ^ 1) = 2 となる
' 0b0100(&H4) -> 0b0010(&H2)

i = 4 << 1 ' 算術左シフト : i = 4 * (2 ^ 1) = 8 となる
' 0b0100(&H4) -> 0b1000(&H8)

i = 7 >> 2 ' 算術右シフト : i = 7 \ (2 ^ 2) = 1 となる
' 0b0111(&H7) -> 0b0001(&H1)

i = 3 << 2 ' 算術左シフト : i = 3 * (2 ^ 2) = 12 となる
' 0b0011(&H3) -> 0b1100(&HC)

i = 5
i = i >> 1 ' 算術右シフト : i = 2
i = i << 3 ' 算術左シフト : i = 16

また、ビットシフトと代入を同時に行う複合代入演算子も用意されています。

Dim i As Integer

i = 5
i >>= 1 ' 算術右シフト : i = 2
i <<= 3 ' 算術左シフト : i = 16

論理シフトを行う演算子は存在しないため、論理シフトを行いたい場合はUnsigned型を使います。