Opérateurs au niveau du bit et opérateurs de décalage (référence C#)Bitwise and shift operators (C# reference)

Les opérateurs suivants effectuent des opérations de décalage ou de décalage avec des opérands des types numériques intégrals ou du type d’omble :The following operators perform bitwise or shift operations with operands of the integral numeric types or the char type:

Ces opérateurs sont définis pour les types int, uint, long et ulong.Those operators are defined for the int, uint, long, and ulong types. Lorsque les deux opérandes sont d’autres types intégraux (sbyte, byte, short, ushort ou char), leurs valeurs sont converties en valeurs de type int, qui est également le type de résultat d’une opération.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. Lorsque les opérandes sont de différents types intégraux, leurs valeurs sont converties vers le type intégral le plus proche.When operands are of different integral types, their values are converted to the closest containing integral type. Pour plus d’informations, consultez la section Promotions numériques de la spécification du langage C#.For more information, see the Numeric promotions section of the C# language specification.

Le & |, ^ , et les opérateurs sont bool également définis pour les opérands du type.The &, |, and ^ operators are also defined for operands of the bool type. Pour plus d’informations, consultez Opérateurs logiques booléens.For more information, see Boolean logical operators.

Les opérations de décalage et au niveau du bit ne provoquent jamais de dépassements de capacité et donnent les mêmes résultats dans des contextes checked et unchecked.Bitwise and shift operations never cause overflow and produce the same results in checked and unchecked contexts.

Opérateur de complément de bits ~Bitwise complement operator ~

L’opérateur ~ produit un complément de bits de son opérande en inversant chaque bit :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

Vous pouvez également utiliser le symbole ~ pour déclarer des finaliseurs.You can also use the ~ symbol to declare finalizers. Pour plus d’informations, consultez Finaliseurs.For more information, see Finalizers.

Opérateur de décalage gauche <<Left-shift operator <<

L’opérateur << déplace son opérat gauche à gauche par le nombre de bits définis par son opéra de droite.The << operator shifts its left-hand operand left by the number of bits defined by its right-hand operand.

L’opération de décalage gauche supprime les bits d’ordre supérieur qui sont en dehors de la plage du type de résultat, et définit les positions de bits vides d’ordre inférieur sur zéro, comme le montre l’exemple suivant :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

Étant donné que les opérateurs de décalage sont définis uniquement pour les types int, uint, long et ulong, le résultat d’une opération contient toujours au moins 32 bits.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. Si l’opérande de partie gauche est d’un autre type intégral (sbyte, byte, short, ushort ou char), sa valeur est convertie en type int, comme l’indique l’exemple suivant :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

Pour plus d’informations sur la façon dont l’opérande de partie droite de l’opérateur << définit la valeur de décalage, consultez la section Valeur de décalage des opérateurs de décalage.For information about how the right-hand operand of the << operator defines the shift count, see the Shift count of the shift operators section.

Opérateur de décalage vers la droite >>Right-shift operator >>

L’opérateur >> déplace son opéra de gauche à droite par le nombre de bits définis par son opéra de droite.The >> operator shifts its left-hand operand right by the number of bits defined by its right-hand operand.

L’opération de décalage vers la droite ignore les bits d’ordre inférieur, comme le montre l’exemple suivant :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

Les positions de bits vides d’ordre supérieur sont définies en fonction du type de l’opérande de partie gauche comme suit :The high-order empty bit positions are set based on the type of the left-hand operand as follows:

  • Si l’opérande gauche int est longde type ou, l’opérateur de virage à droite effectue un changement arithmétique : la valeur du bit le plus significatif (le bit de signe) de l’opératoire gauche est propagée aux positions de bit vide de haut ordre.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. Autrement dit, les positions de bits vides d’ordre supérieur sont définies sur zéro si l’opérande de partir gauche n’est pas négatif et sur un s’il est négatif.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
    
  • Si l’opératoire gauche uint est ulongde type ou, l’opérateur de virage à droite effectue un changement logique : les positions de bits vides de haut ordre sont toujours réglées à zéro.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
    

Pour plus d’informations sur la façon dont l’opérande de partie droite de l’opérateur >> définit la valeur de décalage, consultez la section Valeur de décalage des opérateurs de décalage.For information about how the right-hand operand of the >> operator defines the shift count, see the Shift count of the shift operators section.

Logique ET opérateur&Logical AND operator &

L’opérateur & calcule le AND logique au niveau du bit de ses opérandes :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

Pour bool les opérands, l’opérateur & calcule la logique ET de ses opérandes.For bool operands, the & operator computes the logical AND of its operands. L’opérateur unaire & est l’opérateur address-of.The unary & operator is the address-of operator.

L’opérateur OR exclusif logique ^Logical exclusive OR operator ^

L’opérateur ^ calcule le OR exclusif logique au niveau du bit (également appelé XOR logique au niveau du bit) de ses opérandes.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

Pour bool les opérands, l’opérateur ^ calcule la logique exclusive OR de ses opérandes.For bool operands, the ^ operator computes the logical exclusive OR of its operands.

L’opérateur OU logique |Logical OR operator |

L’opérateur | calcule le OR logique au niveau du bit de ses opérandes :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

Pour bool les opérandes, l’opérateur | calcule la DO logique de ses opérandes.For bool operands, the | operator computes the logical OR of its operands.

Assignation composéeCompound assignment

Pour un opérateur binaire op, une expression d’assignation composée du formulaireFor a binary operator op, a compound assignment expression of the form

x op= y

équivaut à :is equivalent to

x = x op y

sauf que x n’est évalué qu’une seule fois.except that x is only evaluated once.

L’exemple suivant montre l’utilisation de l’assignation composée avec des opérateurs de décalage et des opérateurs au niveau du bit :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}");

En raison des promotions numériques, le résultat de l’opération op risque de ne pas être implicitement convertible en type T de x.Because of numeric promotions, the result of the op operation might be not implicitly convertible to the type T of x. Dans ce cas, si op est un opérateur prédéfini et que le résultat de l’opération est explicitement convertible en type T de x, une expression d’assignation composée de la forme x op= y équivaut à x = (T)(x op y), sauf que x n’est évalué qu’une seule fois.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. L’exemple suivant illustre ce comportement :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

Précédence des opérateursOperator precedence

La liste suivante présente les opérateurs au niveau du bit et les opérateurs de décalage par ordre de précédence, de la plus élevée à la plus basse :The following list orders bitwise and shift operators starting from the highest precedence to the lowest:

  • Opérateur de complément de bits ~Bitwise complement operator ~
  • Opérateurs de décalage << et >>Shift operators << and >>
  • L’opérateur AND logique &Logical AND operator &
  • Opérateur OR exclusif logique ^Logical exclusive OR operator ^
  • Opérateur OR logique |Logical OR operator |

Utilisez des parenthèses, (), pour modifier l’ordre d’évaluation imposé par la précédence des opérateurs :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}");

Pour la liste complète des opérateurs C’commandés par niveau de préséance, voir la section De préséance de l’opérateur de l’article des opérateurs C.For the complete list of C# operators ordered by precedence level, see the Operator precedence section of the C# operators article.

Valeur de décalage des opérateurs de décalageShift count of the shift operators

Pour les << opérateurs >>de quarts et , le type int de l’opéra de droite doit être intou un type qui a une conversion numérique implicite prédéfinie à .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.

Pour les expressions x << count et x >> count, la valeur réelle du décalage varie selon le type de x :For the x << count and x >> count expressions, the actual shift count depends on the type of x as follows:

  • Si le x type int uintde est ou , le nombre de décalage est défini par le bas-ordre cinq bits de l’opéra de droite.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. La valeur de décalage est donc calculée à partir de count & 0x1F (ou de count & 0b_1_1111).That is, the shift count is computed from count & 0x1F (or count & 0b_1_1111).

  • Si le x type long ulongde est ou , le nombre de décalage est défini par l’ordre bas six bits de l’opéra de droite.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. La valeur de décalage est donc calculée à partir de count & 0x3F (ou de count & 0b_11_1111).That is, the shift count is computed from count & 0x3F (or count & 0b_11_1111).

L’exemple suivant illustre ce comportement :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

Notes

Comme le montre l’exemple précédent, le résultat d’une opération de quart peut être non nul, même si la valeur de l’opéra de droite est supérieure au nombre de bits dans l’opéra de gauche.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.

Opérateurs logiques d’énumérationEnumeration logical operators

Le ~ &, |, ^ et les opérateurs sont également pris en charge par tout type de recensement.The ~, &, |, and ^ operators are also supported by any enumeration type. Pour les opérandes du même type d’énumération, une opération logique est effectuée sur les valeurs correspondantes du type intégral sous-jacent.For operands of the same enumeration type, a logical operation is performed on the corresponding values of the underlying integral type. Par exemple, pour tout x et y d’un type énumération T avec un type sous-jacent U, l’expression x & y produit le même résultat que l’expression (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.

Vous utilisez généralement des opérateurs logiques bitwise avec un type d’énumération qui est défini avec l’attribut Drapeaux.You typically use bitwise logical operators with an enumeration type that is defined with the Flags attribute. Pour plus d’informations, consultez la section Types énumération comme indicateurs binaires de l’articleTypes énumération.For more information, see the Enumeration types as bit flags section of the Enumeration types article.

Capacité de surcharge de l’opérateurOperator overloadability

Un type défini par l’utilisateur >> &peut | surcharger le ~, <<, , , et ^ les opérateurs.A user-defined type can overload the ~, <<, >>, &, |, and ^ operators. Quand un opérateur binaire est surchargé, l’opérateur d’assignation composée correspondant est aussi implicitement surchargé.When a binary operator is overloaded, the corresponding compound assignment operator is also implicitly overloaded. Un type défini par l’utilisateur ne peut pas surcharger explicitement un opérateur d’assignation composée.A user-defined type cannot explicitly overload a compound assignment operator.

Si un type T défini par l’utilisateur surcharge l’opérateur << ou >>, l’opérande de partie gauche doit être de type T et l’opérande de partie droite de type 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.

spécification du langage C#C# language specification

Pour plus d’informations, consultez les sections suivantes de la spécification du langage C# :For more information, see the following sections of the C# language specification:

Voir aussiSee also