1. Décalage binaire à gauche
Java dispose également de 3 opérateurs de décalage bit à bit : Si vous en avez vraiment besoin, vous pouvez très simplement décaler tous les bits d'un nombre de plusieurs positions vers la gauche ou vers la droite.
Pour décaler les bits d'un nombre vers la gauche, vous avez besoin de l' opérateur de décalage à gauche au niveau du bit . C'est comme ça que c'est écrit :
a << b
Où a
est le nombre dont les bits sont décalés, et b
est un nombre qui indique combien de fois décaler les bits du nombre a
vers la gauche. Lors de cette opération, les bits de poids faible ajoutés à droite sont des zéros.
Exemples:
Exemple | Résultat |
---|---|
|
|
|
|
|
|
|
|
Décaler un chiffre vers la gauche a le même effet que multiplier un nombre par 2.
Vous voulez multiplier un nombre par 16 ? 16 est égal à 2 4 . Donc tu décales le nombre de 4 chiffres vers la gauche
2. Décalage au niveau du bit vers la droite
Les bits peuvent également être décalés vers la droite. Pour ce faire, utilisez l' opérateur de décalage droit au niveau du bit . C'est comme ça que c'est écrit :
a >> b
Où a
est le nombre dont les bits sont décalés, et b
est le nombre de fois pour décaler les bits du nombre a
vers la droite.
Exemples:
Exemple | Résultat |
---|---|
|
|
|
|
|
|
|
|
Décaler un chiffre vers la droite a le même effet que diviser un nombre par 2.
Lors de cette opération, les bits de poids fort ajoutés à gauche sont des zéros, mais pas toujours !
Le bit le plus à gauche d'un nombre signé est appelé bit de signe : si le nombre est positif, il l'est 0
; mais si le nombre est négatif, ce bit est 1
.
Lors du décalage des bits d'un nombre vers la droite, la valeur du bit de signe se décalerait normalement également et le signe du nombre serait perdu. En conséquence, pour les nombres négatifs (où le bit le plus à gauche est 1
), ce bit reçoit un traitement spécial. Lors du décalage des bits d'un nombre vers la droite, a 0
est ajouté à gauche si le bit le plus à gauche était 0
, et a 1
est ajouté à gauche si le bit le plus à gauche était 1
.
Mais dans l'exemple ci-dessus, cela ne semble pas être le résultat. Pourquoi? Parce que les littéraux entiers sont int
s, et signifient en fait . C'est-à-dire que le bit le plus à gauche est zéro.0b11111111
0b00000000000000000000000011111111
De nombreux programmeurs sont frustrés par ce comportement de décalage vers la droite et préféreraient que le nombre soit toujours rempli de zéros. Java a donc ajouté un autre opérateur de décalage à droite .
C'est comme ça que c'est écrit :
a >>> b
Où a
est le nombre dont les bits sont décalés, et b
est le nombre de fois pour décaler les bits du nombre a
vers la droite. Cet opérateur ajoute toujours des zéros à gauche, quelle que soit la valeur d'origine du bit de signe du nombre a
.
3. Travailler avec des drapeaux
Les programmeurs ont créé un domaine d'étude presque entièrement nouveau sur la base d'opérations bit à bit et de décalage : travailler avec des drapeaux.
Lorsque les ordinateurs avaient très peu de mémoire, il était très populaire de regrouper beaucoup d'informations en un seul numéro. Un nombre était traité comme un tableau de bits : un int correspond à 32 bits et un long à 64 bits.
Vous pouvez écrire beaucoup d'informations dans un tel nombre, surtout si vous avez besoin de stocker des valeurs logiques ( true
ou false
). Un single long
est comme un boolean
tableau composé de 64 éléments. Ces bits étaient appelés flags et étaient manipulés à l'aide des opérations suivantes :
-
définir le drapeau(faire un bit spécifique égal à
1
) -
drapeau de réinitialisation(faire un bit spécifique égal à
0
) -
vérifier le drapeau(vérifier la valeur d'un bit spécifique)
Et voici comment cela se passe avec les opérateurs au niveau du bit.
Pose d'un drapeau
Pour définir un bit spécifique sur 1
, vous devez effectuer une opération OU au niveau du bit entre le nombre dont vous souhaitez définir le bit et un nombre spécialement créé, où seul ce bit est 1
.
Par exemple, supposons que vous ayez le nombre 0b00001010
et que vous deviez définir le 5ème bit sur 1
. Dans ce cas, vous devez :
0b00001010 | 0b00010000 = 0b00011010
Si le 5e bit avait déjà été défini sur un, rien n'aurait changé.
En général, l'opération de positionnement d'un drapeau peut être écrite comme suit
a | (1 << b)
Où a
est le nombre dont le bit sera défini sur 1
. Et b
est la position du bit à régler. L'utilisation de l'opérateur de décalage à gauche est très pratique ici, car vous pouvez immédiatement dire avec quel bit nous travaillons.
Réinitialiser un drapeau
Pour réinitialiser un bit spécifique (c'est-à-dire le régler sur 0
) sans perturber les autres bits, vous devez effectuer une &
opération entre le nombre dont vous souhaitez réinitialiser le bit (c'est-à-dire le régler sur 0
) et un nombre spécialement créé, où tous les bits sont égaux à 1
sauf pour le bit que vous souhaitez réinitialiser.
Par exemple, supposons que vous ayez le nombre 0b00001010
et que vous deviez définir le 4ème bit sur 0
. Dans ce cas, vous devez :
0b00001010 & 0b11110111 = 0b00000010
Si le 4ème bit avait déjà été mis à zéro, alors rien n'aurait changé.
De manière générale, l'opération de remise à zéro d'un drapeau peut s'écrire comme suit
a & ~(1 << b)
Où a
est le nombre dont le bit sera réinitialisé à 0
. Et b
c'est la position du bit à effacer.
Pour obtenir un nombre où tous les bits sont 1
sauf celui que nous voulons être zéro, nous décalons d'abord 1 b positions vers la gauche, puis utilisons l' NOT
opérateur au niveau du bit pour inverser le résultat.
Vérification d'un drapeau
En plus de définir ou de réinitialiser un indicateur spécifique, il vous suffit parfois de vérifier si un indicateur donné est défini, c'est-à-dire si un certain bit est égal à 1
. C'est assez facile à faire avec un bitwise &
.
Par exemple, supposons que vous deviez vérifier si le 4e bit est défini sur 1
dans le nombre 0b00001010
. Ensuite, vous devez faire ceci :
if ( (0b00001010 & 0b00001000) == 0b00001000 )
En général, l'opération de vérification d'un drapeau peut s'écrire comme suit
(a & (1 << b)) == (1 << b)
Où a
est le nombre dont le bit est vérifié. Et b
est la position du bit à vérifier.
4. Cryptage
L' XOR
opération au niveau du bit est souvent utilisée par les programmeurs pour un chiffrement simple. En général, un tel cryptage ressemble à ceci :
result = number ^ password;
Où number
se trouvent les données que nous voulons crypter, password
est un numéro spécial utilisé comme "mot de passe" pour les données, et result
est le numéro crypté.
number == (number ^ password) ^ password;
L'important ici est que lorsque l' XOR
opérateur est appliqué deux fois à un numéro, il produit le numéro d'origine, quel que soit le "mot de passe".
Pour récupérer number
du encrypted result
, il vous suffit de refaire l'opération :
original number = result ^ password;
Exemple:
class Solution
{
public static int[] encrypt(int[] data, int password)
{
int[] result = new int[data.length];
for (int i = 0; i < data.length; i++)
result[i] = data[i] ^ password;
return result;
}
public static void main(String[] args)
{
int[] data = {1, 3, 5, 7, 9, 11};
int password = 199;
// Encrypt the array of data
int[] encrypted = encrypt(data, password);
System.out.println(Arrays.toString(encrypted));
// Decrypt the array of data
int[] decrypted = encrypt(encrypted, password);
System.out.println(Arrays.toString(decrypted));
}
}
GO TO FULL VERSION