位元與移位運算子 (C# 參考)Bitwise and shift operators (C# reference)

下列運算子會使用 整數數數值型別char 類型的運算元來執行位 or 移位運算: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.

&|^ 運算子也會針對類型的運算元而定義 boolThe &, |, and ^ operators are also defined for operands of the bool type. 如需詳細資訊,請參閱布林邏輯運算子For more information, see Boolean logical operators.

位元和移位運算子一律不會導致溢位,並會在受檢查內容及未受檢查內容中產生相同的結果。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. 如需詳細資訊,請參閱完成項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:

  • 如果左邊運算元的類型是 intlong ,則右移運算子會執行 算術 移位:左邊運算元 (正負號位) 的最大位值會傳播到高序位的空白位位置。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. 也就是說,若左邊運算元不是負值且在為負值時被設定為一,則高位空位元位置會被設定為零。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
    
  • 如果左邊運算元的類型是 uintulong ,則右移運算子會執行 邏輯 移位:高序位空白位位置一律設定為零。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 運算元, & 運算子會計算其運算元的 邏輯 ANDFor bool operands, the & operator computes the logical AND of its operands. 一元的 & 運算子是 address-of 運算子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 運算元, ^ 運算子會計算其運算元的 邏輯互斥 ORFor 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 運算元, | 運算子會計算其運算元的 邏輯 ORFor bool operands, the | operator computes the logical OR of its operands.

複合指派Compound assignment

若是二元運算子 op,表單的複合指派運算式For a binary operator op, a compound assignment expression of the form

x op= y

相當於is equivalent to

x = x op y

但只會評估 x 一次。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 作業結果可能無法隱含轉換成 xT 型別。Because of numeric promotions, the result of the op operation might be not implicitly convertible to the type T of x. 在此情況下,如果 op 是預先定義的運算子,且作業結果可以明確轉換成 xT 型別,則形式 x op= y 的複合指派運算式相等於 x = (T)(x op y),唯一的不同在於 x 只會評估一次。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 或具有 預先定義之隱含數值轉換 的型別 intFor 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 << countx >> count 運算式,實際的移位計數取決於 x 的型別,如下所示:For the x << count and x >> count expressions, the actual shift count depends on the type of x as follows:

  • 如果的類型 xintuint ,則移位元數目會由右邊運算元的低序位 位來定義。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).

  • 如果的類型 xlongulong ,則移位元數目會由右邊運算元的低序位 位定義。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

注意

如先前的範例所示,即使右邊運算元的值大於左運算元中的位數,移位作業的結果也可能為非零。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 列舉型別 Txyx & 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. 當二元運算子多載時,對應的複合指派運算子也會隱含地多載。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,右邊運算元的型別必須是 intIf 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