C#・VBでは言語組み込みのビットごとの演算として、以下のビット演算子が用意されています。 整数型に対して使用することで、ビットごとの演算を行うことができます。 &=
などのように、ビット演算子に=
を後置できる演算子では、代入先を左オペランド(左項)とする複合代入演算子となります。
ビット演算 | 演算子 | |
---|---|---|
C# | VB | |
論理否定(NOT)・1の補数 |
~
|
Not
|
論理積(AND) |
& , &= |
And
|
論理和(OR) |
| , |= |
Or
|
排他的論理和(XOR) |
^ , ^= |
Xor
|
C#におけるビット演算子は、32ビットまたは64ビットの整数型(int
, uint
, long
, uint
)に対してのみ定義されています。 8ビット・16ビット整数型に対してビットごとの演算を行う場合、値は自動的にint
へ拡大変換された上で演算が行われます。 つまり、sbyte
, byte
, char
, short
, ushort
の値に対して演算を行う場合、結果はint
となります。 複合代入演算子を使う場合は、自動的に代入先の型にキャストされます。
NOT・AND・OR・XORの各演算子を使ってビット演算を行う
using System;
static class Sample {
static void Main()
{
int x = 0x55AA_00FF;
int y = 0x5A5A_0F0F;
int not_x = ~x; // NOT(論理否定)
int x_or_y = x | y; // OR(論理和)
int x_and_y = x & y; // AND(論理積)
int x_xor_y = x ^ y; // XOR(排他的論理和)
Console.WriteLine("~{0} = {1}", x.ToBinary(), not_x.ToBinary());
Console.WriteLine("{0} | {1} = {2}", x.ToBinary(), y.ToBinary(), x_or_y.ToBinary());
Console.WriteLine("{0} & {1} = {2}", x.ToBinary(), y.ToBinary(), x_and_y.ToBinary());
Console.WriteLine("{0} ^ {1} = {2}", x.ToBinary(), y.ToBinary(), x_xor_y.ToBinary());
byte bx = 0x00; // 8ビット整数
byte by = 0xFF;
// ビット演算子では8ビット・16ビットの整数型はintに拡大変換した上で演算されるため、
// 結果を8ビット・16ビットの整数型に代入する場合は明示的にキャストする必要がある
byte b1 = (byte)~bx;
byte b2 = (byte)(bx & by);
bx &= by; // 複合代入演算子の場合はキャストする必要はない
}
#region "数値を二進数表記の文字列化するためのメソッド"
static string ToBinary(this int number) => "0b_" + Convert.ToString(number, 2).PadLeft(8 * sizeof(int), '0');
#endregion
}
実行結果
~0b_01010101101010100000000011111111 = 0b_10101010010101011111111100000000 0b_01010101101010100000000011111111 | 0b_01011010010110100000111100001111 = 0b_01011111111110100000111111111111 0b_01010101101010100000000011111111 & 0b_01011010010110100000111100001111 = 0b_01010000000010100000000000001111 0b_01010101101010100000000011111111 ^ 0b_01011010010110100000111100001111 = 0b_00001111111100000000111111110000
上記の演算子をbool
・Boolean
に対して使用すると、ビットごとの演算ではなく単一のブール値に対する演算を行う論理演算子となります。 ただしVBでは、ブール値に対して論理積・論理和を求める場合は通常AndAlso
・OrElse
演算子を使います 詳細は論理演算子 §.AndAlso演算子・OrElse演算子を参照してください。
ビット演算子はFlags属性を持つ列挙体に対しても使用することができます。 (列挙体とフラグ)