« Salut Amigo ! »

"J'aimerais aussi parler des masques de bits et de XOR."

"Vous savez déjà que les nombres sont constitués de bits et vous pouvez effectuer diverses opérations sur ces bits. Un masque de bits est une représentation de plusieurs valeurs logiques différentes (valeurs vrai/faux) sous la forme d'un seul entier. Dans ce cas, chaque valeur booléenne correspond à un peu spécifique. Voici comment cela pourrait être fait :"

"La représentation binaire des puissances de deux (1, 2, 4, 8, 16, 32, ...) n'implique la définition que d'un bit :"

Nombre Représentation binaire
1 0000 0001
2 0000 0010
4 0000 0100
8 0000 1000
16 0001 0000
19 (pas une puissance de deux) 0001 0011
31 (pas une puissance de deux) 0001 1111

"Ainsi, tout entier peut être traité comme un tableau de bits ou un tableau de valeurs booléennes."

"Voici comment vous pouvez stocker différentes valeurs booléennes dans un seul nombre :"

Valeurs booléennes
boolean a = true;
boolean b = false;
boolean c = true;
boolean d = false;
Valeurs regroupées en un seul chiffre :
int result = 0;
 if (a) result += 1; // 1 == 20 — bit 0
 if (b) result += 2; // 2 == 21 — bit 1
 if (c) result += 4; // 4 == 22 — bit 2
 if (d) result += 8; // 8 == 23 — bit 3

"Maintenant, chaque bit vaut 1 si la variable booléenne correspondante était vraie."

Dans notre cas, les variables a et c étaient vraies, donc le résultat est égal à 1+4 == 5

0000 0101
0000 dcba

"Je pense que je sais ce qui se passe."

"Eh bien, si vous comprenez, passons à autre chose."

"Un int a 32 bits. L'un d'eux est utilisé pour le signe du nombre, et les 31 autres peuvent être utilisés pour stocker les valeurs de 31 variables booléennes."

"Un long a 64 bits où nous pouvons stocker 63 variables booléennes."

"Ouais."

"Des dizaines de variables entassées dans un seul chiffre. C'est pas mal."

"Mais où est-ce appliqué?"

"Principalement dans les situations où vous avez besoin de stocker beaucoup d'informations sur les objets. Lorsque vous stockez beaucoup d'informations sur un objet, il y a toujours quelques dizaines de variables booléennes. "Avec cette approche, elles sont toutes stockées de manière pratique dans un seul numéro ."

"En mettant l'accent sur le mot 'stocké'. Parce qu'en fait, utiliser le numéro n'est pas si pratique."

« Au fait, c'est exactement ce que je voulais demander. Comment extraire la valeur booléenne du nombre ? »

"Ce n'est pas compliqué du tout. Disons que vous devez déterminer si le bit 6 est défini sur 1 (2 à la puissance cinq est 32). Nous pourrions vérifier comme ceci :"

Combinez les nombres en un :
int a = 32; // 25 == 0010 0000
int b = 8; // 23 == 0000 1000
int c = 2; // 21 == 0000 0010

int result = a + b + c; // 32 + 8 + 2 == 42 == 0010 1010
Extrayez des valeurs en vérifiant des bits spécifiques :
int a = result & 32; // 0010 1010 & 0010 0000 = 0010 0000
int b = result & 8; // 0010 1010 & 0000 1000 = 0000 1000
int c = result & 2; // 0010 1010 & 0000 0010 = 0000 0010

"Ainsi, travailler avec des masques de bits implique trois opérations :"

1)  Mettre un bit spécifique à 0

2)  Réglez un bit spécifique sur 1

3)  Vérifiez la valeur du bit spécifique.

"Prenez le bit 6, par exemple."

"Comment réglez-vous le bit 6 sur 1 ?"

Code Description
result = result | 01000000;
result |= 01000000;
Comment mettre le bit 6 à 1 ?
result = result & 10111111;
result &= 10111111;
Comment mettre le bit 6 à 0 ?
c = result & 01000000;
Comment obtenir la valeur du bit 6 ?

"C'est très inhabituel, mais pas difficile. Mec, maintenant je suis un programmeur hors pair."

"Et encore une petite astuce sur la façon d'obtenir facilement des nombres avec un bit spécifique défini sur 0 ou 1 : 01000000 ou 10111111."

Pour cela, nous avons les  opérateurs >> et  << .

"1 est 2 à la puissance zéro. En d'autres termes, un nombre avec le bit 0 défini sur 1. Nous avons besoin d'un nombre avec le bit 6 défini."

int c = 1 << 6; // 0000 0001 << 6 == 0100 0000 == 64

« Cool ! C'est vraiment utile dans de tels cas.

"Mais que se passe-t-il si j'ai besoin d'un nombre où chaque bit est défini sur 1, sauf qu'un bit spécifique est défini sur 0 ?"

"Ce n'est pas difficile non plus :"

int d = ~(1 << 6); // ~0100 0000 == 10111111

"En d'autres termes, tout est très simple :"

Code Description
result = result | (1 << 6);
result |= (1 << 6);
Comment mettre le bit 6 à 1 ?
result = result & ~(1 << 6);
result &= ~(1 << 6);
Comment mettre le bit 6 à 0 ?
c = result & (1 << 6);
Comment obtenir la valeur du bit 6 ?

« Ça n'a pas l'air très difficile. Mais je ne m'en souviendrai pas tout de suite.

"Mais, si vous rencontrez une expression effrayante telle que "résultat &= ~(1 << 6)" dans le code de quelqu'un d'autre, vous saurez que cette personne travaille simplement avec un masque de bits."

"Et si vous le rencontrez souvent, il se souviendra de lui-même pour vous."

"Se souvenir de lui-même... Ça sonne bien. Merci pour la leçon."