Opérateurs Java Bitwise

1. Vue d'ensemble

Les opérateurs sont utilisés dans le langage Java pour opérer sur des données et des variables.

Dans ce didacticiel, nous explorerons les opérateurs Bitwise et leur fonctionnement en Java.

2. Opérateurs au niveau du bit

Les opérateurs au niveau du bit fonctionnent sur des chiffres binaires ou des bits de valeurs d'entrée. Nous pouvons les appliquer aux types entiers - long, int, short, char et byte.

Avant d'explorer les différents opérateurs au niveau du bit, comprenons d'abord leur fonctionnement.

Les opérateurs au niveau du bit fonctionnent sur un équivalent binaire de nombres décimaux et effectuent des opérations sur eux bit par bit selon l'opérateur donné:

  • Tout d'abord, les opérandes sont convertis en leur représentation binaire
  • Ensuite, l'opérateur est appliqué à chaque nombre binaire et le résultat est calculé
  • Enfin, le résultat est reconverti dans sa représentation décimale

Comprenons avec un exemple; prenons deux entiers:

int value1 = 6; int value2 = 5;

Ensuite, appliquons un opérateur OR au niveau du bit à ces nombres:

int result = 6 | 5;

Pour effectuer cette opération, tout d'abord, la représentation binaire de ces nombres sera calculée:

Binary number of value1 = 0110 Binary number of value2 = 0101

Ensuite, l'opération sera appliquée à chaque bit. Le résultat renvoie un nouveau nombre binaire:

0110 0101 ----- 0111

Enfin, le résultat 0111 sera reconverti en décimal qui est égal à 7 :

result : 7

Les opérateurs au niveau du bit sont en outre classés comme des opérateurs de décalage logique et au niveau du bit. Passons maintenant en revue chaque type.

3. Opérateurs logiques au niveau du bit

Les opérateurs logiques au niveau du bit sont AND (&), OR (|), XOR (^) et NOT (~).

3.1. OU au niveau du bit (|)

L'opérateur OR compare chaque chiffre binaire de deux entiers et renvoie 1 si l'un d'eux est égal à 1.

Ceci est similaire au || opérateur logique utilisé avec des booléens. Lorsque deux booléens sont comparés, le résultat est vrai si l'un d'eux est vrai. De même, la sortie est 1 lorsque l'un ou l'autre est 1.

Nous avons vu un exemple de cet opérateur dans la section précédente:

@Test public void givenTwoIntegers_whenOrOperator_thenNewDecimalNumber()  value2; assertEquals(7, result); 

Voyons la représentation binaire de cette opération:

0110 0101 ----- 0111

Ici, nous pouvons voir que l'utilisation de OR, 0 et 0 entraînera 0, tandis que toute combinaison avec au moins un 1 entraînera 1.

3.2. ET au niveau du bit (&)

L'opérateur AND compare chaque chiffre binaire de deux entiers et renvoie 1 si les deux sont 1, sinon il renvoie 0.

Ceci est similaire à l'opérateur && avec des valeurs booléennes . Lorsque les valeurs de deux booléens sont vraies, le résultat d'une opération && est vrai.

Utilisons le même exemple que ci-dessus, sauf que nous utilisons maintenant l'opérateur & au lieu de | opérateur:

@Test public void givenTwoIntegers_whenAndOperator_thenNewDecimalNumber() { int value1 = 6; int value2 = 5; int result = value1 & value2; assertEquals(4, result); }

Voyons également la représentation binaire de cette opération:

0110 0101 ----- 0100

0100 est 4 en décimal, par conséquent, le résultat est:

result : 4

3.3. XOR au niveau du bit (^)

L'opérateur XOR compare chaque chiffre binaire de deux entiers et renvoie 1 si les deux bits comparés sont différents. Cela signifie que si les bits des deux entiers sont 1 ou 0, le résultat sera 0; sinon, le résultat sera 1:

@Test public void givenTwoIntegers_whenXorOperator_thenNewDecimalNumber() { int value1 = 6; int value2 = 5; int result = value1 ^ value2; assertEquals(3, result); }

Et la représentation binaire:

0110 0101 ----- 0011

0011 est 3 en décimal, par conséquent, le résultat est:

result : 3

3.4. COMPLEMENT au niveau du bit (~)

L'opérateur Bitwise Not ou Complement signifie simplement la négation de chaque bit de la valeur d'entrée. Il ne prend qu'un seul entier et c'est équivalent au! opérateur.

Cet opérateur change chaque chiffre binaire de l'entier, ce qui signifie que tous les 0 deviennent 1 et tous les 1 deviennent 0. Le! L'opérateur fonctionne de la même manière pour les valeurs booléennes : il inverse les valeurs booléennes de vrai à faux et vice versa.

Voyons maintenant avec un exemple comment trouver le complément d'un nombre décimal.

Faisons le complément de valeur1 = 6:

@Test public void givenOneInteger_whenNotOperator_thenNewDecimalNumber() { int value1 = 6; int result = ~value1; assertEquals(-7, result); }

La valeur en binaire est:

value1 = 0000 0110

En appliquant l'opérateur complément, le résultat sera:

0000 0110 -> 1111 1001

This is the one’s complement of the decimal number 6. And since the first (leftmost) bit is 1 in binary, it means that the sign is negative for the number that is stored.

Now, since the numbers are stored as 2’s complement, first we need to find its 2’s complement and then convert the resultant binary number into a decimal number:

1111 1001 -> 0000 0110 + 1 -> 0000 0111

Finally, 0000 0111 is 7 in decimal. Since the sign bit was 1 as mentioned above, therefore the resulting answer is:

result : -7

3.5. Bitwise Operator Table

Let's summarize the result of the operators we've seen to so far in a comparison table:

A B A|B A&B A^B ~A 0 0 0 0 0 1 1 0 1 0 1 0 0 1 1 0 1 1 1 1 1 1 0 0

4. Bitwise Shift Operators

Binary shift operators shift all the bits of the input value either to the left or right based on the shift operator.

Let's see the syntax for these operators:

value  

The left side of the expression is the integer that is shifted, and the right side of the expression denotes the number of times that it has to be shifted.

Bitwise shift operators are further classified as bitwise left and bitwise right shift operators.

4.1. Signed Left Shift [<<]

The left shift operator shifts the bits to the left by the number of times specified by the right side of the operand. After the left shift, the empty space in the right is filled with 0.

Another important point to note is that shifting a number by one is equivalent to multiplying it by 2, or, in general, left shifting a number by n positions is equivalent to multiplication by 2^n.

Let's take the value 12 as the input value.

Now, we will move it by 2 places to the left (12 <<2) and see what will be the final result.

The binary equivalent of 12 is 00001100. After shifting to the left by 2 places, the result is 00110000, which is equivalent to 48 in decimal:

@Test public void givenOnePositiveInteger_whenLeftShiftOperator_thenNewDecimalNumber() { int value = 12; int leftShift = value << 2; assertEquals(48, leftShift); } 

This works similarly for a negative value:

@Test public void givenOneNegativeInteger_whenLeftShiftOperator_thenNewDecimalNumber() { int value = -12; int leftShift = value << 2; assertEquals(-48, leftShift); }

4.2. Signed Right Shift [>>]

The right shift operator shifts all the bits to the right. The empty space in the left side is filled depending on the input number:

  • When an input number is negative, where the leftmost bit is 1, then the empty spaces will be filled with 1
  • When an input number is positive, where the leftmost bit is 0, then the empty spaces will be filled with 0

Let's continue the example using 12 as input.

Now, we will move it by 2 places to the right(12 >>2) and see what will be the final result.

The input number is positive, so after shifting to the right by 2 places, the result is 0011, which is 3 in decimal:

@Test public void givenOnePositiveInteger_whenSignedRightShiftOperator_thenNewDecimalNumber() { int value = 12; int rightShift = value >> 2; assertEquals(3, rightShift); }

Also, for a negative value:

@Test public void givenOneNegativeInteger_whenSignedRightShiftOperator_thenNewDecimalNumber() { int value = -12; int rightShift = value >> 2; assertEquals(-3, rightShift); }

4.3. Unsigned Right Shift [>>>]

This operator is very similar to the signed right shift operator. The only difference is that the empty spaces in the left are filled with 0 irrespective of whether the number is positive or negative. Therefore, the result will always be a positive integer.

Let's right shift the same value of 12:

@Test public void givenOnePositiveInteger_whenUnsignedRightShiftOperator_thenNewDecimalNumber() { int value = 12; int unsignedRightShift = value >>> 2; assertEquals(3, unsignedRightShift); }

And now, the negative value:

@Test public void givenOneNegativeInteger_whenUnsignedRightShiftOperator_thenNewDecimalNumber() { int value = -12; int unsignedRightShift = value >>> 2; assertEquals(1073741821, unsignedRightShift); }

5. Difference Between Bitwise and Logical Operators

There are a few differences between the bitwise operators we've discussed here and the more commonly known logical operators.

First, logical operators work on boolean expressions and return boolean values (either true or false), whereas bitwise operators work on binary digits of integer values (long, int, short, char, and byte) and return an integer.

Also, logical operators always evaluate the first boolean expression and, depending on its result and the operator used, may or may not evaluate the second. On the other hand, bitwise operators always evaluate both operands.

Finally, logical operators are used in making decisions based on multiple conditions, while bitwise operators work on bits and perform bit by bit operations.

6. Cas d'utilisation

Certains cas d'utilisation potentiels des opérateurs bit à bit sont:

  • Piles de communication où les bits individuels dans l'en-tête attachés aux données signifient des informations importantes
  • Dans les systèmes embarqués pour définir / effacer / basculer un seul bit d'un registre spécifique sans modifier les bits restants
  • Pour crypter les données pour des problèmes de sécurité à l'aide de l'opérateur XOR
  • Dans la compression de données en convertissant les données d'une représentation à une autre, pour réduire la quantité d'espace utilisé

7. Conclusion

Dans ce didacticiel, nous avons découvert les types d'opérateurs binaires et en quoi ils diffèrent des opérateurs logiques. Nous avons également vu quelques cas d'utilisation potentiels pour eux.

Tous les exemples de code de cet article sont disponibles à l'adresse over sur GitHub.