ビットごとの演算子とシフト演算子 (C# リファレンス)Bitwise and shift operators (C# reference)

以下の演算子では、整数型または char 型のオペランドに対してビットごとの演算またはシフト演算が実行されます。The following operators perform bitwise or shift operations with operands of the integral numeric types or the char type:

これらの演算子は、intuintlongulong 型に対して定義されています。Those operators are defined for the int, uint, long, and ulong types. 両方のオペランドが他の整数型 (sbytebyteshortushortchar) の場合、それらの値は int 型に変換され、演算の結果もその型になります。When both operands are of other integral types (sbyte, byte, short, ushort, or char), their values are converted to the int type, which is also the result type of an operation. オペランドが異なる整数型の場合、それらの値は最も近い含んでいる整数型に変換されます。When operands are of different integral types, their values are converted to the closest containing integral type. 詳しくは、「C# 言語仕様」の「数値の上位変換」セクションをご覧ください。For more information, see the Numeric promotions section of the C# language specification.

&|^ の各演算子は、bool 型のオペランドに対しても定義されています。The &, |, and ^ operators are also defined for operands of the bool type. 詳しくは、「ブール論理演算子」をご覧ください。For more information, see Boolean logical operators.

ビットごとの演算子およびシフト演算が原因でオーバーフローが発生することはなく、checked と unchecked のコンテキストで同じ結果が生成されることはありません。Bitwise and shift operations never cause overflow and produce the same results in checked and unchecked contexts.

ビットごとの補数演算子 ~Bitwise complement operator ~

~ 演算子では、各ビットを反転させることにより、オペランドのビットごとの補数が生成されます。The ~ operator produces a bitwise complement of its operand by reversing each bit:

uint a = 0b_0000_1111_0000_1111_0000_1111_0000_1100;
uint b = ~a;
Console.WriteLine(Convert.ToString(b, toBase: 2));
// Output:
// 11110000111100001111000011110011

~ シンボルはファイナライザーの宣言にも使用できます。You can also use the ~ symbol to declare finalizers. 詳細については、「Finalizers」 (ファイナライザー) を参照してください。For more information, see Finalizers.

左シフト演算子 <<Left-shift operator <<

<< 演算子では、左側のオペランドが、右側のオペランドで定義されたビット数だけ左にシフトされます。The << operator shifts its left-hand operand left by the number of bits defined by its right-hand operand.

次の例に示すように、左シフト演算子では、結果の型の範囲外にある上位ビットは破棄され、空の下位ビット位置は、ゼロに設定されます。The left-shift operation discards the high-order bits that are outside the range of the result type and sets the low-order empty bit positions to zero, as the following example shows:

uint x = 0b_1100_1001_0000_0000_0000_0000_0001_0001;
Console.WriteLine($"Before: {Convert.ToString(x, toBase: 2)}");

uint y = x << 4;
Console.WriteLine($"After:  {Convert.ToString(y, toBase: 2)}");
// Output:
// Before: 11001001000000000000000000010001
// After:  10010000000000000000000100010000

シフト演算子は intuintlongulong 型に対してのみ定義されるので、演算の結果には常に少なくとも 32 ビットが含まれます。Because the shift operators are defined only for the int, uint, long, and ulong types, the result of an operation always contains at least 32 bits. 左側のオペランドが別の整数型 (sbytebyteshortushortchar) の場合、次の例で示すように、その値は int 型に変換されます。If the left-hand operand is of another integral type (sbyte, byte, short, ushort, or char), its value is converted to the int type, as the following example shows:

byte a = 0b_1111_0001;

var b = a << 8;
Console.WriteLine(b.GetType());
Console.WriteLine($"Shifted byte: {Convert.ToString(b, toBase: 2)}");
// Output:
// System.Int32
// Shifted byte: 1111000100000000

<< 演算子の右側のオペランドでのシフト数の定義方法については、「シフト演算子のシフト数」セクションをご覧ください。For information about how the right-hand operand of the << operator defines the shift count, see the Shift count of the shift operators section.

右シフト演算子 >>Right-shift operator >>

>> 演算子では、左側のオペランドが、右側のオペランドで定義されたビット数だけ右にシフトされます。The >> operator shifts its left-hand operand right by the number of bits defined by its right-hand operand.

次の例で示すように、右シフト演算では、下位ビットが破棄されます。The right-shift operation discards the low-order bits, as the following example shows:

uint x = 0b_1001;
Console.WriteLine($"Before: {Convert.ToString(x, toBase: 2), 4}");

uint y = x >> 2;
Console.WriteLine($"After:  {Convert.ToString(y, toBase: 2), 4}");
// Output:
// Before: 1001
// After:    10

空の上位ビット位置は、左側のオペランドの型に基づいて次のように設定されます。The high-order empty bit positions are set based on the type of the left-hand operand as follows:

  • 左側のオペランドの型が int または long である場合、右シフト演算子では、"算術" シフトが実行されます: 左側のオペランドの最上位ビット (符号ビット) の値が空の上位ビット位置に反映されます。If the left-hand operand is of type int or long, the right-shift operator performs an arithmetic shift: the value of the most significant bit (the sign bit) of the left-hand operand is propagated to the high-order empty bit positions. つまり、左側のオペランドが負でない場合は空の上位ビット位置が 0 に設定され、負の場合は 1 に設定されます。That is, the high-order empty bit positions are set to zero if the left-hand operand is non-negative and set to one if it's negative.

    int a = int.MinValue;
    Console.WriteLine($"Before: {Convert.ToString(a, toBase: 2)}");
    
    int b = a >> 3;
    Console.WriteLine($"After:  {Convert.ToString(b, toBase: 2)}");
    // Output:
    // Before: 10000000000000000000000000000000
    // After:  11110000000000000000000000000000
    
  • 左側のオペランドの型が uint または ulong である場合、右シフト演算子では、"論理" シフトが実行されます: 空の上位ビット位置は常に 0 に設定されます。If the left-hand operand is of type uint or ulong, the right-shift operator performs a logical shift: the high-order empty bit positions are always set to zero.

    uint c = 0b_1000_0000_0000_0000_0000_0000_0000_0000;
    Console.WriteLine($"Before: {Convert.ToString(c, toBase: 2), 32}");
    
    uint d = c >> 3;
    Console.WriteLine($"After:  {Convert.ToString(d, toBase: 2), 32}");
    // Output:
    // Before: 10000000000000000000000000000000
    // After:     10000000000000000000000000000
    

>> 演算子の右側のオペランドでのシフト数の定義方法については、「シフト演算子のシフト数」セクションをご覧ください。For information about how the right-hand operand of the >> operator defines the shift count, see the Shift count of the shift operators section.

論理 AND 演算子 &Logical AND operator &

& 演算子によって、その整数オペランドのビットごとの論理 AND が計算されます。The & operator computes the bitwise logical AND of its integral operands:

uint a = 0b_1111_1000;
uint b = 0b_1001_1101;
uint c = a & b;
Console.WriteLine(Convert.ToString(c, toBase: 2));
// Output:
// 10011000

bool オペランドの場合、& 演算子がそのオペランドの論理 AND を計算します。For bool operands, the & operator computes the logical AND of its operands. 単項 & 演算子はアドレス演算子です。The unary & operator is the address-of operator.

論理排他的 OR 演算子: ^Logical exclusive OR operator ^

^ 演算子によって、その整数オペランドのビットごとの論理排他的 OR (ビットごとの論理 XOR とも呼ばれます) が計算されます。The ^ operator computes the bitwise logical exclusive OR, also known as the bitwise logical XOR, of its integral operands:

uint a = 0b_1111_1000;
uint b = 0b_0001_1100;
uint c = a ^ b;
Console.WriteLine(Convert.ToString(c, toBase: 2));
// Output:
// 11100100

bool オペランドの場合、^ 演算子がそのオペランドの論理排他的 OR を計算します。For bool operands, the ^ operator computes the logical exclusive OR of its operands.

論理 OR 演算子 |Logical OR operator |

| 演算子によって、その整数オペランドのビットごとの論理 OR が計算されます。The | operator computes the bitwise logical OR of its integral operands:

uint a = 0b_1010_0000;
uint b = 0b_1001_0001;
uint c = a | b;
Console.WriteLine(Convert.ToString(c, toBase: 2));
// Output:
// 10110001

bool オペランドの場合、| 演算子がそのオペランドの論理 OR を計算します。For bool operands, the | operator computes the logical OR of its operands.

複合代入。Compound assignment

2 項演算子 op の場合、フォームの複合代入式For a binary operator op, a compound assignment expression of the form

x op= y

上記の式は、次の式と同じです。is equivalent to

x = x op y

ただし、x が評価されるのは 1 回だけです。except that x is only evaluated once.

次の例では、ビットごとの演算子およびシフト演算子を使った複合代入の使用方法を示します。The following example demonstrates the usage of compound assignment with bitwise and shift operators:

uint a = 0b_1111_1000;
a &= 0b_1001_1101;
Display(a);  // output: 10011000

a |= 0b_0011_0001;
Display(a);  // output: 10111001

a ^= 0b_1000_0000;
Display(a);  // output:   111001

a <<= 2;
Display(a);  // output: 11100100

a >>= 4;
Display(a);  // output:     1110

void Display(uint x) => Console.WriteLine($"{Convert.ToString(x, toBase: 2), 8}");

数値の上位変換のため、op 演算の結果は、x の型 T に暗黙的に変換できない可能性があります。Because of numeric promotions, the result of the op operation might be not implicitly convertible to the type T of x. そのような場合、op が定義済みの演算子であり、演算の結果が x の型 T に明示的に変換できる場合、x op= y の形式の複合代入式は、x が 1 回だけ評価される点を除き、x = (T)(x op y) と等価です。In such a case, if op is a predefined operator and the result of the operation is explicitly convertible to the type T of x, a compound assignment expression of the form x op= y is equivalent to x = (T)(x op y), except that x is only evaluated once. 次の例は、その動作を示します。The following example demonstrates that behavior:

byte x = 0b_1111_0001;

int b = x << 8;
Console.WriteLine($"{Convert.ToString(b, toBase: 2)}");  // output: 1111000100000000

x <<= 8;
Console.WriteLine(x);  // output: 0

演算子の優先順位Operator precedence

次のビットごとの演算子およびシフト演算子の一覧は、優先度が高い順に並べられています。The following list orders bitwise and shift operators starting from the highest precedence to the lowest:

  • ビットごとの補数演算子 ~Bitwise complement operator ~
  • シフト演算子 << および >>Shift operators << and >>
  • 論理 AND 演算子 &Logical AND operator &
  • 論理排他的 OR 演算子 ^Logical exclusive OR operator ^
  • 論理 OR 演算子 |Logical OR operator |

演算子の優先順位によって定められた評価の順序を変更するには、かっこ () を使用します。Use parentheses, (), to change the order of evaluation imposed by operator precedence:

uint a = 0b_1101;
uint b = 0b_1001;
uint c = 0b_1010;

uint d1 = a | b & c;
Display(d1);  // output: 1101

uint d2 = (a | b) & c;
Display(d2);  // output: 1000

void Display(uint x) => Console.WriteLine($"{Convert.ToString(x, toBase: 2), 4}");

優先度順に並べられた C# 演算子の完全な一覧については、C# 演算子に関する記事の「演算子の優先順位」セクションを参照してください。For the complete list of C# operators ordered by precedence level, see the Operator precedence section of the C# operators article.

シフト演算子のシフト数Shift count of the shift operators

シフト演算子 << および >> の場合、右側のオペランドの型は、int であるか、または int への事前に定義された暗黙的な数値変換を持つ型にする必要があります。For the shift operators << and >>, the type of the right-hand operand must be int or a type that has a predefined implicit numeric conversion to int.

x << count および x >> count の式では、実際のシフト数は次のように x の型によって異なります。For the x << count and x >> count expressions, the actual shift count depends on the type of x as follows:

  • x の型が int または uint である場合、シフト数は、右側のオペランドの下位 5 ビットで定義されます。If the type of x is int or uint, the shift count is defined by the low-order five bits of the right-hand operand. つまり、シフト数は count & 0x1F (または count & 0b_1_1111) から計算されます。That is, the shift count is computed from count & 0x1F (or count & 0b_1_1111).

  • x の型が long または ulong である場合、シフト数は、右側のオペランドの下位 6 ビットで定義されます。If the type of x is long or ulong, the shift count is defined by the low-order six bits of the right-hand operand. つまり、シフト数は count & 0x3F (または count & 0b_11_1111) から計算されます。That is, the shift count is computed from count & 0x3F (or count & 0b_11_1111).

次の例は、その動作を示します。The following example demonstrates that behavior:

int count1 = 0b_0000_0001;
int count2 = 0b_1110_0001;

int a = 0b_0001;
Console.WriteLine($"{a} << {count1} is {a << count1}; {a} << {count2} is {a << count2}");
// Output:
// 1 << 1 is 2; 1 << 225 is 2

int b = 0b_0100;
Console.WriteLine($"{b} >> {count1} is {b >> count1}; {b} >> {count2} is {b >> count2}");
// Output:
// 4 >> 1 is 2; 4 >> 225 is 2

注意

前の例で示したように、右側のオペランドの値が左側のオペランドのビット数よりも大きい場合でも、シフト演算の結果が 0 以外になることがあります。As the preceding example shows, the result of a shift operation can be non-zero even if the value of the right-hand operand is greater than the number of bits in the left-hand operand.

列挙論理演算子Enumeration logical operators

~&|^ の演算子は、任意の列挙型でもサポートされます。The ~, &, |, and ^ operators are also supported by any enumeration type. オペランドが同じ列挙型の場合、基になっている整数型の対応する値に対して、論理演算が実行されます。For operands of the same enumeration type, a logical operation is performed on the corresponding values of the underlying integral type. たとえば、基になる型が U である列挙型 T の任意の xy に対して、式 x & y では式 (T)((U)x & (U)y) と同じ結果が生成されます。For example, for any x and y of an enumeration type T with an underlying type U, the x & y expression produces the same result as the (T)((U)x & (U)y) expression.

通常、ビットごとの論理演算子は、Flags 属性で定義されている列挙型で使います。You typically use bitwise logical operators with an enumeration type that is defined with the Flags attribute. 詳しくは、「列挙型」記事の「ビット フラグとしての列挙型」セクションをご覧ください。For more information, see the Enumeration types as bit flags section of the Enumeration types article.

演算子のオーバーロード可/不可Operator overloadability

ユーザー定義型では、~<<>>&|^ の各演算子をオーバーロードできます。A user-defined type can overload the ~, <<, >>, &, |, and ^ operators. 2 項演算子をオーバーロードすると、対応する複合代入演算子も暗黙的にオーバーロードされます。When a binary operator is overloaded, the corresponding compound assignment operator is also implicitly overloaded. ユーザー定義型は、複合代入演算子を明示的にオーバーロードすることはできません。A user-defined type cannot explicitly overload a compound assignment operator.

ユーザー定義型 T<< または >> 演算子をオーバーロードする場合、左側のオペランドの型は T である必要があり、右側のオペランドの型は int である必要があります。If a user-defined type T overloads the << or >> operator, the type of the left-hand operand must be T and the type of the right-hand operand must be int.

C# 言語仕様C# language specification

詳細については、「C# 言語仕様」の次のセクションを参照してください。For more information, see the following sections of the C# language specification:

参照See also