Bitweise und Schiebeoperatoren: C#-ReferenzBitwise and shift operators (C# reference)

Mit den folgenden Operatoren werden bitweise oder Verschiebevorgänge mit Operanden durchgeführt, die integrale numerische Typen oder den char-Typ aufweisen:The following operators perform bitwise or shift operations with operands of the integral numeric types or the char type:

Diese Operatoren werden für die Typen int, uint, long und ulong definiert.Those operators are defined for the int, uint, long, and ulong types. Wenn beide Operanden andere integrale Typen aufweisen (sbyte, byte, short, ushort oder char), werden ihre Werte in den Typ int konvertiert. Hierbei handelt es sich auch um den Ergebnistyp einer Operation.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. Wenn die Operanden abweichende integrale Typen aufweisen, werden ihre Werte in den enthaltenden integralen Typ konvertiert, der am besten geeignet ist.When operands are of different integral types, their values are converted to the closest containing integral type. Weitere Informationen finden Sie im Abschnitt Numerische Heraufstufungen der Spezifikation für die Sprache C#.For more information, see the Numeric promotions section of the C# language specification.

Die Operatoren &, | und ^ werden auch für Operanden des bool-Typs definiert.The &, |, and ^ operators are also defined for operands of the bool type. Weitere Informationen finden Sie unter Logische boolesche Operatoren.For more information, see Boolean logical operators.

Bitweise und Schiebeoperationen verursachen niemals Überläufe und führen sowohl in geprüften als auch in ungeprüften Kontexten zu identischen Ergebnissen.Bitwise and shift operations never cause overflow and produce the same results in checked and unchecked contexts.

Bitweiser Komplementoperator ~Bitwise complement operator ~

Mit dem Operator ~ wird ein bitweises Komplement seines Operanden erzeugt, indem jedes Bit umgekehrt wird: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

Sie können das Symbol ~ auch verwenden, um Finalizers zu deklarieren.You can also use the ~ symbol to declare finalizers. Weitere Informationen finden Sie unter Finalizer.For more information, see Finalizers.

Operator für Linksverschiebung <<Left-shift operator <<

Mit dem Operator << wird der linke Operand um die Anzahl von Bits nach links verschoben, die durch den rechten Operanden angegeben wird.The << operator shifts its left-hand operand left by the number of bits defined by its right-hand operand.

Bei der Operation zum Verschieben nach links werden die hohen Bits, die außerhalb des Bereichs des Ergebnistyps liegen, verworfen, und die niedrigen leeren Bitpositionen werden auf null festgelegt. Dies ist im folgenden Beispiel dargestellt: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

Da die Verschiebeoperatoren nur für die Typen int, uint, long und ulong definiert werden, enthält das Ergebnis einer Operation immer mindestens 32 Bit.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. Wenn der linke Operand einen abweichenden integralen Typ aufweist (sbyte, byte, short, ushort oder char), wird sein Wert in den Typ int konvertiert. Dies ist im folgenden Beispiel dargestellt: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

Informationen dazu, wie der rechte Operand des Operators << die Anzahl für die Verschiebung definiert, finden Sie im Abschnitt Anzahl für die Verschiebung durch Schiebeoperatoren.For information about how the right-hand operand of the << operator defines the shift count, see the Shift count of the shift operators section.

Operator für Rechtsverschiebung >>Right-shift operator >>

Mit dem Operator >> wird der linke Operand um die Anzahl von Bits nach rechts verschoben, die durch den rechten Operanden angegeben wird.The >> operator shifts its left-hand operand right by the number of bits defined by its right-hand operand.

Bei der Operation zum Verschieben nach rechts werden die niedrigen Bits verworfen. Dies ist im folgenden Beispiel dargestellt: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

Die höheren leeren Bitpositionen werden basierend auf dem Typ des linken Operanden wie folgt festgelegt:The high-order empty bit positions are set based on the type of the left-hand operand as follows:

  • Wenn der linke Operand vom Typ int oder long ist, führt der Operator zur Rechtsverschiebung eine arithmetische Verschiebung durch: Der Wert des Bits mit dem höchsten Stellenwert (MSB, „most significant bit“) des linken Operanden wird auf die hohen leeren Bitpositionen übertragen.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. Die hohen leeren Bitpositionen werden daher auf 0 festgelegt, wenn der linke Operand nicht negativ ist, bzw. auf 1, wenn der linke Operand negativ ist.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
    
  • Wenn der linke Operand vom Typ uint oder ulong ist, führt der Operator zur Rechtsverschiebung eine logische Verschiebung durch: Die hohen leeren Bitpositionen werden immer auf 0 (null) festgelegt.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
    

Informationen dazu, wie der rechte Operand des Operators >> die Anzahl für die Verschiebung definiert, finden Sie im Abschnitt Anzahl für die Verschiebung durch Schiebeoperatoren.For information about how the right-hand operand of the >> operator defines the shift count, see the Shift count of the shift operators section.

Logischer AND-Operator &Logical AND operator &

Mit dem Operator & wird „bitweises logisches UND“ für die Operanden berechnet:The & operator computes the bitwise logical AND of its operands:

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

Für bool-Operanden berechnet der &-Operator das logische UND für die Operanden.For bool operands, the & operator computes the logical AND of its operands. Der unäre &-Operator ist der address-of-Operator.The unary & operator is the address-of operator.

Logischer exklusiver OR-Operator: ^Logical exclusive OR operator ^

Mit dem Operator ^ wird „bitweises logisches exklusives ODER“, auch als „bitweises logisches XOR“ bezeichnet, seiner Operanden berechnet:The ^ operator computes the bitwise logical exclusive OR, also known as the bitwise logical XOR, of its operands:

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

Für bool-Operanden berechnet der ^-Operator das logische exklusive ODER für die Operanden.For bool operands, the ^ operator computes the logical exclusive OR of its operands.

Logischer OR-Operator: |Logical OR operator |

Mit dem Operator | wird „bitweises logisches ODER“ der Operanden berechnet:The | operator computes the bitwise logical OR of its operands:

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

Für bool-Operanden berechnet der |-Operator das logische ODER für die Operanden.For bool operands, the | operator computes the logical OR of its operands.

VerbundzuweisungCompound assignment

Bei einem binären Operator op entspricht ein Verbundzuweisungsausdruck der FormFor a binary operator op, a compound assignment expression of the form

x op= y

für die folgende Syntax:is equivalent to

x = x op y

außer dass x nur einmal überprüft wird.except that x is only evaluated once.

Im folgenden Beispiel wird die Verwendung von Verbundzuweisungen mit bitweisen und Schiebeoperatoren veranschaulicht: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}");

Aufgrund von numerischen Höherstufungen kann das Ergebnis der Operation op ggf. nicht implizit in den Typ T von x konvertiert werden.Because of numeric promotions, the result of the op operation might be not implicitly convertible to the type T of x. In diesem Fall gilt Folgendes: Wenn op ein vordefinierter Operator ist und das Ergebnis der Operation explizit in den Typ T von x konvertiert werden kann, entspricht ein Verbundzuweisungsausdruck der Form x op= y dem Ausdruck x = (T)(x op y). Der einzige Unterschied ist, dass x nur einmal ausgewertet wird.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. Das folgende Beispiel veranschaulicht dieses Verhalten: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

OperatorrangfolgeOperator precedence

In der folgenden Liste sind die bitweisen und Schiebeoperatoren absteigend nach Rangfolge sortiert:The following list orders bitwise and shift operators starting from the highest precedence to the lowest:

  • Bitweiser Komplementoperator ~Bitwise complement operator ~
  • Schiebeoperatoren << und >>Shift operators << and >>
  • Logischer AND-Operator &Logical AND operator &
  • Logischer exklusiver OR-Operator ^Logical exclusive OR operator ^
  • Logischer OR-Operator |Logical OR operator |

Verwenden Sie Klammern (), wenn Sie die Reihenfolge der Auswertung ändern möchten, die durch Operatorrangfolge festgelegt wird: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}");

Die vollständige Liste der nach Rangfolgenebene sortierten C#-Operatoren finden Sie im Abschnitt Operatorrangfolge im Artikel C#-Operatoren.For the complete list of C# operators ordered by precedence level, see the Operator precedence section of the C# operators article.

Anzahl für die Verschiebung durch SchiebeoperatorenShift count of the shift operators

Für die Schiebeoperatoren << und >> muss der Typ des rechten Operanden int lauten oder ein Typ sein, der eine vordefinierte, implizite numerische Konvertierung in int aufweist.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.

Für die Ausdrücke x << count und x >> count hängt die tatsächliche Verschiebungsanzahl wie folgt vom Typ von x ab:For the x << count and x >> count expressions, the actual shift count depends on the type of x as follows:

  • Lautet der Typ von x``int oder uint, wird die Verschiebungsanzahl durch die niedrigen fünf Bits des rechten Operanden definiert.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. Die Verschiebungsanzahl errechnet sich daher aus count & 0x1F (oder count & 0b_1_1111).That is, the shift count is computed from count & 0x1F (or count & 0b_1_1111).

  • Lautet der Typ von x``long oder ulong, wird die Verschiebungsanzahl durch die niedrigen sechs Bits des rechten Operanden definiert.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. Die Verschiebungsanzahl errechnet sich daher aus count & 0x3F (oder count & 0b_11_1111).That is, the shift count is computed from count & 0x3F (or count & 0b_11_1111).

Das folgende Beispiel veranschaulicht dieses Verhalten: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

Hinweis

Wie im vorherigen Beispiel gezeigt wird, kann das Ergebnis eines Verschiebungsvorgangs nicht 0 (Null) sein, auch wenn der Wert des rechten Operanden größer ist als die Anzahl der Bits im linken Operanden.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.

Logische EnumerationsoperatorenEnumeration logical operators

Die Operatoren ~, &, | und ^ werden auch von jedem Enumerationstyp unterstützt.The ~, &, |, and ^ operators are also supported by any enumeration type. Für Operanden mit dem gleichen Enumerationstyp wird ein logischer Vorgang für die entsprechenden Werte des zugrunde liegenden integralen Typs durchgeführt.For operands of the same enumeration type, a logical operation is performed on the corresponding values of the underlying integral type. Für alle x- und y-Elemente des Enumerationstyps T mit dem zugrunde liegenden Typ U führt der Ausdruck x & y zum gleichen Ergebnis wie der Ausdruck (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.

Normalerweise verwenden Sie bitweise logische Operatoren mit einem Enumerationstyp, der mit dem Flags-Attribut definiert wird.You typically use bitwise logical operators with an enumeration type that is defined with the Flags attribute. Weitere Informationen finden Sie im Abschnitt Enumerationstypen als Bitflags des Artikels Enumerationstypen.For more information, see the Enumeration types as bit flags section of the Enumeration types article.

OperatorüberladbarkeitOperator overloadability

Ein benutzerdefinierter Typ kann die Operatoren ~, <<, >>, &, | und ^überladen.A user-defined type can overload the ~, <<, >>, &, |, and ^ operators. Wenn ein binärer Operator überladen ist, wird der zugehörige Verbundzuweisungsoperator implizit auch überladen.When a binary operator is overloaded, the corresponding compound assignment operator is also implicitly overloaded. Ein benutzerdefinierter Typ kann einen Verbundzuweisungsoperator nicht explizit überladen.A user-defined type cannot explicitly overload a compound assignment operator.

Wenn ein benutzerdefinierter Typ T den Operator << oder >> überlädt, muss der Typ des linken Operanden T und der Typ des rechten Operanden int lauten.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#-SprachspezifikationC# language specification

Weitere Informationen finden Sie in den folgenden Abschnitten der C#-Sprachspezifikation:For more information, see the following sections of the C# language specification:

Siehe auchSee also