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ビット目

16進数表記・2進数表記や桁区切り記号、またサフィックスによる型を指定した数値表記等についてより詳しくはリテラルとサフィックス §.整数リテラルおよびリテラルとサフィックス §.サフィックスを参照してください。

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メソッドに書式指定子XBを指定する方法があります。 書式指定子Bは、.NET 8以降で使用できます。

ToStringメソッドを使って16進数・2進数表記で文字列化する例 .NET 8
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"),  bitsOr.ToString("B64"))
Console.WriteLine("{0} {1}", bitsAnd.ToString("X8"), bitsAnd.ToString("B64"))
Console.WriteLine("{0} {1}", bitsXor.ToString("X8"), bitsXor.ToString("B64"))
Console.WriteLine("{0} {1}", bitsNot.ToString("X8"), bitsNot.ToString("B64"))
実行結果
0000000D 0000000000000000000000000000000000000000000000000000000000001101
12000078 0000000000000000000000000000000000010010000000000000000001111000
00FFFF00 0000000000000000000000000000000000000000111111111111111100000000
FF00FF00 0000000000000000000000000000000011111111000000001111111100000000

また、Convert.ToStringメソッドを使う方法もあります。

Convert.ToStringメソッドを使って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}", Convert.ToString(bitsOr, 8),  Convert.ToString(bitsOr, 2))
Console.WriteLine("{0} {1}", Convert.ToString(bitsAnd, 8), Convert.ToString(bitsAnd, 2))
Console.WriteLine("{0} {1}", Convert.ToString(bitsXor, 8), Convert.ToString(bitsXor, 2))
Console.WriteLine("{0} {1}", Convert.ToString(bitsNot, 8), Convert.ToString(bitsNot, 2))
実行結果
15 1101
2200000170 10010000000000000000001111000
77777400 111111111111111100000000
37700177400 11111111000000001111111100000000

16進数表記・2進数表記での文字列化、基数変換についてより詳しくはビット演算 §.数値・文字列間での基数変換を参照してください。

ビットシフト演算子

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

ビットシフト演算子の動作についてより詳しくはビット演算 §.シフト演算子を参照してください。

また、.NET Core 3.0/.NET 5以降では、BitOperations.RotateLeftメソッドBitOperations.RotateRightメソッドを用いることで回転シフト(循環シフト)を行うこともできます。 これについて詳しくはビット演算 §.左回転シフト・右回転シフト (RotateLeft・RotateRight)にて解説しています。

演算子以外のビット演算

言語組み込みの演算子を使用するほかに、.NETではBitOperationsクラスに用意されているビット演算メソッドを使用することができます。 具体的な使い方や使用できるメソッドについてはビット演算 §.BitOperationsクラスにて解説しています。