CodeGym /Blog Java /Random-FR /Opérateurs Java au niveau du bit
Auteur
Alex Vypirailenko
Java Developer at Toshiba Global Commerce Solutions

Opérateurs Java au niveau du bit

Publié dans le groupe Random-FR
Dans la leçon d'aujourd'hui, nous allons nous familiariser avec les opérateurs Java Bitwise et examiner des exemples sur la façon de les utiliser. Vous connaissez probablement le mot "bit". Sinon, rappelons ce que cela signifie :) Un bit est la plus petite unité d'information dans un ordinateur. Son nom vient du chiffre binaire . Un bit peut être exprimé par l'un des deux nombres suivants : 1 ou 0. Il existe un système de nombres binaires spécial basé sur des uns et des zéros. Nous n'allons pas plonger ici dans une jungle mathématique. Nous noterons seulement que n'importe quel nombre en Java peut être converti en forme binaire. Pour ce faire, vous devez utiliser les classes wrapper.
Opérateurs au niveau du bit - 1
Par exemple, voici comment procéder pour un int :

public class Main {

   public static void main(String[] args) {

       int x = 342;
       System.out.println(Integer.toBinaryString(x));
   }
}
Sortie console : 101010110 1010 10110 (j'ai ajouté l'espace pour faciliter la lecture) est le nombre 342 dans le système décimal. Nous avons en fait décomposé ce nombre en bits individuels : des zéros et des uns. Les opérations effectuées sur les bits sont appelées bitwise .
  • ~ - PAS au niveau du bit.
Cet opérateur est très simple : il passe sur chaque bit de notre nombre, et retourne le bit : les zéros deviennent des uns, et les uns deviennent des zéros. Si on l'applique à notre nombre 342, voici ce qui se passe : 101010110 est 342 représenté sous forme de nombre binaire 010101001 est la valeur de l'expression ~342 Essayons de mettre cela en pratique :

public class Main {

   public static void main(String[] args) {

       int x = 342;
       System.out.println(~x);
   }
}
Sortie console : 169 169 est notre résultat ( 010101001 ) dans le système décimal familier :)
  • & - AND au niveau du bit
Comme vous pouvez le voir, cela ressemble assez au ET logique ( && ). L' opérateur && , vous vous en souviendrez, ne renvoie vrai que si les deux opérandes sont vrais. Au niveau du bit & fonctionne de manière similaire : il compare deux nombres petit à petit. La comparaison produit un troisième nombre. Prenons par exemple les nombres 277 et 432 : 110110000 est 277 représenté sous forme de nombre binaire 1000101011 est 432 représenté sous forme de nombre binaire Ensuite, l'opérateur & compare le premier bit du nombre supérieur au premier bit du nombre inférieur. Comme il s'agit d'un opérateur ET, le résultat sera 1 uniquement si les deux bits sont 1. Dans tous les autres cas, le résultat est 0. 100010101 && opérateur Tout d'abord, nous comparons les premiers bits des deux nombres, puis les seconds bits, puis les troisièmes, et ainsi de suite. Comme vous pouvez le voir, dans seulement deux cas, les deux bits correspondants dans les nombres sont égaux à 1 (les premier et cinquième bits). Toutes les autres comparaisons ont produit des 0. Donc au final nous avons obtenu le nombre 10001000. Dans le système décimal, cela correspond au nombre 272. Vérifions :

public class Main {

   public static void main(String[] args) {
       System.out.println(277&432);
   }
}
Sortie console : 272
  • | - OR au niveau du bit.
Cet opérateur fonctionne de la même manière : comparer deux nombres bit à bit. Seulement maintenant si au moins un des bits est 1, alors le résultat est 1. Regardons les mêmes nombres (277 et 432) : 100010101 | 110110000 _______________ 110110101 - résultat du | opérateur Ici, nous obtenons un résultat différent : les seuls bits qui restent des zéros sont les bits qui étaient des zéros dans les deux nombres. Le résultat est le nombre 110110101. Dans le système décimal, il correspond au nombre 437. Vérifions :

public class Main {

   public static void main(String[] args) {
       System.out.println(277|432);
   }
}
Sortie console : 437 Nous avons tout calculé correctement ! :)
  • ^ - XOR au niveau du bit (OU exclusif)
Nous n'avons pas encore rencontré cet opérateur. Mais il n'y a rien de compliqué là-dedans. Il est similaire à l'opérateur OR ordinaire. Il y a une différence : le OU ordinaire renvoie vrai si au moins un opérande est vrai. Mais il n'est pas nécessaire qu'il en soit un : si les deux opérandes sont vrais, le résultat est vrai. Mais OU exclusif ne renvoie vrai que si exactement l'un des opérandes est vrai. Si les deux opérandes sont vrais, le OU ordinaire renvoie vrai ("au moins un vrai"), mais XOR renvoie faux. C'est pourquoi on l'appelle OU exclusif. En connaissant le fonctionnement des opérateurs bitwise précédents, vous pouvez probablement facilement calculer 277 ^ 432. Mais approfondissons-le ensemble une fois de plus :) 100010101 ^ 110110000 _______________ 010100101 - résultat du ^opérateur C'est notre résultat. Les bits qui étaient identiques dans les deux nombres produisent un 0 (ce qui signifie que le test "un seul" a échoué). Mais les bits qui formaient une paire 0-1 ou 1-0 sont devenus des uns. Notre résultat est le nombre 010100101. Dans le système décimal, cela correspond au nombre 165. Voyons si nos calculs sont corrects :

public class Main {

   public static void main(String[] args) {
       System.out.println(277^432);
   }
}
Sortie console : Super 165 ! Tout est comme nous le pensions :) Il est maintenant temps de se familiariser avec les opérateurs de décalage de bits. Le nom parle de lui-même. Nous prenons un certain nombre et déplaçons ses bits vers la gauche ou vers la droite :) Voyons à quoi cela ressemble :

Décalage à gauche

Un décalage de bits vers la gauche est indiqué par << Voici un exemple :

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 3;// Shift distance

       int z = (x << y);
       System.out.println(Integer.toBinaryString(x));
       System.out.println(Integer.toBinaryString(z));
   }
}
Dans cet exemple, le nombre x = 64 est appelé la valeur. Ce sont les bits de la valeur que nous allons décaler. Nous allons décaler les bits vers la gauche (vous auriez pu le deviner par la direction de l' opérateur << ) Dans le système binaire, le nombre 64 = 1000000 Le nombre y = 3 est appelé distance de décalage. La distance de décalage indique de combien de bits vers la droite/gauche vous voulez décaler les bits du nombre x Dans notre exemple, nous allons les décaler de 3 bits vers la gauche. Pour voir plus clairement le processus de changement de vitesse, regardez l'image. Dans cet exemple, nous utilisons int s. Les entiers occupent 32 bits dans la mémoire de l'ordinateur. Voici à quoi ressemble notre numéro 64 d'origine :
Opérateurs au niveau du bit - 2
Et maintenant, nous prenons chacun de nos bits et les décalons littéralement vers la gauche de 3 positions :
Opérateurs au niveau du bit - 3
Jetez un oeil à ce que nous avons. Comme vous pouvez le voir, tous nos bits ont été décalés et 3 autres zéros ont été ajoutés à partir du bord de la plage. Trois, parce que nous avons décalé de 3. Si nous avions décalé de 10, 10 zéros auraient été ajoutés. Ainsi, l'expression x << y signifie "décaler les bits du nombre x vers la gauche de y places". Le résultat de notre expression est le nombre de 1000000000, qui est 512 dans le système décimal. Allons vérifier:

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 3;// Shift distance

       int z = (x << y);
       System.out.println(z);
   }
}
Sortie console : 512 Spot on ! Théoriquement, les bits pourraient être décalés à l'infini, mais comme notre nombre est un int , nous n'avons que 32 chiffres binaires disponibles. Parmi ceux-ci, 7 sont déjà occupés par 64 (1000000). Par conséquent, si nous décalions 27 positions vers la gauche, notre seule se déplacerait au-delà de la plage du type de données et serait perdue. Seuls les zéros resteraient !

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 26;// Shift distance

       int z = (x << y);
       System.out.println(z);
   }
}
Sortie de la console : 0 Comme prévu, celui-ci a dépassé les 32 bits disponibles et a disparu. Nous avons terminé avec un nombre de 32 bits composé uniquement de zéros.
Opérateurs au niveau du bit - 4
Naturellement, cela correspond à 0 dans le système décimal. Voici une règle simple pour se souvenir des décalages vers la gauche : Pour chaque décalage vers la gauche, le nombre est multiplié par 2. Essayons de calculer l'expression suivante sans images de bits 111111111 << 3 Nous devons multiplier le nombre 111111111 par 2 . En conséquence, nous obtenons 888888888. Écrivons du code et vérifions :

public class Main {

   public static void main(String[] args) {
       System.out.println(111111111 << 3);
   }
}
Sortie console : 888888888

Décalage à droite

Cette opération est notée >> . Il fait la même chose, mais dans l'autre sens ! :) Nous ne réinventerons pas la roue. Essayons avec le même int 64.

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 2;// Shift distance

       int z = (x >> y);
       System.out.println(z);
   }
}
Opérateurs au niveau du bit - 5
Opérateurs au niveau du bit - 6
À la suite d'un décalage vers la droite de 2, les deux zéros extrêmes de notre nombre sortent de la plage et sont perdus. Nous obtenons 10000, ce qui correspond au nombre 16 dans la sortie de la console du système décimal : 16 Voici une règle simple pour se souvenir des décalages vers la droite : chaque décalage vers la droite divise par deux, en supprimant tout reste. Par exemple, 35 >> 2 signifie que nous devons diviser 35 par 2 deux fois, en écartant les restes 35/2 = 17 (écarter le reste 1) 17/2 = 8 (écarter le reste 1) À la fin, 35 >> 2 devrait soit égal à 8. Vérifions :

public class Main {

   public static void main(String[] args) {
       System.out.println(35 >> 2);
   }
}
Sortie console : 8

Priorité des opérateurs en Java

Lors de l'écriture et de la lecture de code, vous trouverez souvent des expressions qui combinent plusieurs opérations. Il est très important de comprendre l'ordre dans lequel elles seront exécutées (sinon, vous pourriez être surpris par le résultat) Parce que Java a beaucoup d'opérations, chacune d'elles s'est vu attribuer une place dans une table spéciale :

Priorité de l'opérateur

Les opérateurs Priorité
suffixe expr++ expr--
unaire ++expr --expr +expr ~ !
Multiplicatif * / %
additif + -
changement << >> >>>
relationnel < > <= >= instancede
égalité == !=
ET au niveau du bit &
OU exclusif au niveau du bit ^
OU inclusif au niveau du bit |
ET logique &&
OU logique ||
ternaire ? :
mission = += -= *= /= %= &= ^= |= <<= >>= >>>=
Toutes les opérations sont effectuées de gauche à droite, en tenant compte de leur priorité. Par exemple, si nous écrivons

int x  = 6 - 4/2;
alors l'opération de division ( 4/2 ) sera effectuée en premier. Bien qu'il vienne en deuxième position, il a une priorité plus élevée. Les parenthèses et les crochets indiquent la priorité maximale. Vous vous en souvenez probablement à l'école. Par exemple, si vous les ajoutez à l'expression

int x  = (6 - 4)/2;
alors la soustraction est effectuée en premier, car elle est entre parenthèses. La priorité de l'opérateur logique && est plutôt faible (voir le tableau), il sera donc généralement le dernier. Par exemple:

boolean x = 6 - 4/2 > 3 && 12*12 <= 119;
Cette expression sera exécutée comme suit :
  • 4/2 = 2

boolean x = 6 - 2 > 3 && 12*12 <= 119;
  • 12*12 = 144

boolean x = 6 - 2 > 3 && 144 <= 119;
  • 6-2 = 4

boolean x = 4 > 3 && 144 <= 119;
Ensuite, les opérateurs de comparaison sont exécutés :
  • 4 > 3 = vrai

boolean x = true && 144 <= 119;
  • 144 <= 119 = faux

boolean x = true && false;
Et, enfin, l'opérateur AND ( && ) sera exécuté en dernier.

boolean x = true && false;
boolean x = false;
Par exemple, l'opérateur addition( + ) a une priorité plus élevée que l' opérateur de comparaison != (pas égal) ; Ainsi, dans l'expression

boolean x = 7 != 6+1;
l'opération 6+1 sera effectuée en premier, puis la vérification 7 != 7 (qui est évaluée à faux), et enfin l'affectation du résultat (faux) à la variable x (l'affectation a généralement la priorité la plus faible de tous les opérateurs ; voir la table). Phew! C'était une énorme leçon, mais vous l'avez fait! Si vous n'avez pas bien compris certaines de ces leçons ou des leçons précédentes, ne vous inquiétez pas. Nous aborderons ces sujets plus d'une fois à l'avenir. Quelques leçons de CodeGym sur les opérations logiques et numériques. Nous n'y reviendrons pas de si tôt, mais il n'y a aucun mal à ce que vous les lisiez maintenant.
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION