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#におけるプレフィックス0x
・0b
に相当するものです。
さらに、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
16進数表記・2進数表記での文字列化
値を16進数表記・2進数表記で文字列化するには、ToStringメソッドに書式指定子X
・B
を指定する方法があります。 書式指定子B
は、.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メソッドを使う方法もあります。
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クラスにて解説しています。