Visual Basicでは、整数型に対してAnd, Or, Xor, Notの各ビット演算子を用いることができます。 また、VB7.1(VB2003)以降では右シフト>>および左シフト<<ビットシフト演算子を用いることができます。

ビット演算子

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 ' = &B10101010

If b And &H1 Then Console.WriteLine("1ビット目") ' &H1 = &B00000001
If b And &H2 Then Console.WriteLine("2ビット目") ' &H2 = &B00000010
If b And &H4 Then Console.WriteLine("3ビット目") ' &H4 = &B00000100
If b And &H8 Then Console.WriteLine("4ビット目") ' &H8 = &B00001000
実行結果
2ビット目
4ビット目

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

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

16進数表記・2進数表記

ビット演算に際しては、16進数表記・2進数表記がよく用いられます。 VBでは、プレフィックス&Hを用いることで数値を16進数表記で記述することができます。 また、VB 15(Visual Basic 2017)以降では、プレフィックス&Bを用いることで数値を2進数表記で記述することができます。 これらは、C++やC#におけるプレフィックス0x0bに相当するものです。

さらに、VB 15.5以降では、桁区切り記号としてアンダースコア _ を含めて記述することもできます。

Dim hex1 As Integer = &HDEADBEEF   ' 16進数表記の値 (10進数表記で3,735,928,495)
Dim hex2 As Integer = &H_DEAD_BEEF ' 16進数表記の値・桁区切り記号付き (値としては上記と同じ・VB15.5以降)

Dim bin1 As Integer = &B0000111100110101     ' 2進数表記の値 (VB15以降・10進数表記で3,893)
Dim bin2 As Integer = &B_0000_1111_0011_0101 ' 2進数表記の値・桁区切り記号付き (値としては上記と同じ・VB15.5以降)

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

Dim b As Byte = &B10101010

If b And &B00000001 Then Console.WriteLine("1ビット目")
If b And &B00000010 Then Console.WriteLine("2ビット目")
If b And &B00000100 Then Console.WriteLine("3ビット目")
If b And &B00001000 Then Console.WriteLine("4ビット目")
実行結果
2ビット目
4ビット目

さらに、VBではプレフィックス&Oを用いることで8進数表記にすることもできます。 詳しくはリテラルとサフィックス §.8進整数リテラルを参照してください。

列挙体とビット演算

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

Dim attr As FileAttributes

' 読み取り専用でシフテムファイルを表すファイル属性 (ReadOnlyとSystemの2つの値を組み合わせる)
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

ビット演算は、Flags属性が設定されている列挙体に対して行うことができます。 Flags属性について、また列挙体とビットごとの組み合わせについては列挙体とフラグで解説しています。

16進数表記・2進数表記での文字列化

値を16進数表記・2進数表記で文字列化するには、ToStringメソッドに書式指定子Xを指定する、Convert.ToStringメソッドを使うなどの方法があります。 詳しくは書式指定子 §.X, x (hexadecimal/16進数)および基本型の型変換 §.基数を指定した変換 (Convert.ToXXX)を参照してください。

16進数・2進数表記で文字列化する例
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

' 値を16進数・2進数表記で文字列化する
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 となる
' &B0100(&H4) -> &B0010(&H2)

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

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

i = 3 << 2 ' 算術左シフト : i = 3 * (2 ^ 2) = 12 となる
' &B0011(&H3) -> &B1100(&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型を使います。

また、循環シフト(または回転シフトcircular shift)を行う専用の演算子は存在しませんが、.NET Core 3.0以降ではBitOperations.RotateLeftメソッドもしくはBitOperations.RotateRightメソッドを用いることができます。