Opérations sur les bits

1- Bitwise

En programmation informatique numérique, l'opération bitwise fonctionne sur un ou plusieurs chiffres binaires (binary numerals), ou des chaînes qui sont semblables à des nombres binaires. Il s’agit d’une opération simple et rapide, directement prise en charge par le processeur (processor). Normalement, des opérations bitwise sont beaucoup plus rapides que la multiplication, la division, parfois beaucoup plus rapidement que l’addition. Des calculs bitwise utilisent moins d'énergie car ils utilisent rarement des ressources.
Il y a 7 opérateurs  bitwise :
Operator Nom Description
& ET binaire (AND) Renvoie un 1 pour chaque position de bit pour laquelle les bits correspondants des deux opérandes sont des 1, si non il renvoie un 0.
| OU binaire (OR) Renvoie un 1 pour chaque position de bit pour laquelle le bit correspondant d'au moins un des deux opérandes est un 1. Si non il renvoie un 0.
^ OU exclusif binaire (XOR) Renvoie un 1 pour chaque position de bit pour laquelle le bit correspondant d'un seul des deux opérandes est un 1. Si non il renvoie un 0.
~ NON binaire (NOT) Inverse les bits de son opérande: 0 en 1 et 1 en 0.
<< Décalage à gauche (Zero fill left shift) Décale un bit en représentation binaire d'autre bit vers la gauche, en introduisant des zéros par la droite.
>> Décalage à droite avec propagation du signe (Signed right shift) Décale un bit en représentation binaire d'autre bit vers la droite, en rejetant les bits à droite.
>>> Décalage à droite avec introduction de zéros (Zero fill right shift) Décale un bit en représentation binaire d'autre bit vers la droite, en rejetant les bits à droite et en introduisant des zéros par la gauche.

Bitwise AND

Lorsqu'un  bitwise AND est exécuté sur chaque paire de  bit, il donne 1 uniquement si à la fois tous les 2 bit sont 1, si non il donne 0.
L'exemple avec 1 bit :
Operation Result
0 & 0 0
0 & 1 0
1 & 0 0
1 & 1 1
L'exemple avec 4 bit :
Operation Result
1111 & 0000 0000
1111 & 0001 0001
1111 & 0010 0010
1111 & 0100 0100

Bitwise OR:

Lorsqu'un  bitwise OR est effectué sur une paire de  bit, il donne 1 si un des deux  bit vaut 1, si non il renvoie 0.
L'exemple avec 1 bit :
Operation Result
0 | 0 0
0 | 1
1 | 0 1
1 | 1 1
L'exemple avec 4 bit :
Operation Result
1111 | 0000 1111
1111 | 0001 1111
1111 | 0010 1111
1111 | 0100 1111

Bitwise XOR

Lorsqu'un  bitwise XOR est effectué sur chaque paire de  bit, il donne 1 si ses  bit sont différents, si non il donne 0.
L'exemple avec 1 bit :
Operation Result
0 ^ 0 0
0 ^ 1
1 ^ 0 1
1 ^ 1
L'exemple avec 4 bit :
Operation Result
1111 ^ 0000 1111
1111 ^ 0001 1110
1111 ^ 0010 1101
1111 ^ 0100 1011

Bitwise NOT

Lorsqu'un  Bitwise NOT est utilisé, il va renverser tous les  bit. 1 en 0 et 0 en 1.
L'exemple avec 1 bit :
Operation Result
~ 0 1
~ 1 0
L'exemple avec 4 bit :
Operation Result
~ 0000 1111
~ 0001 0001
~ 0010 1101
~ 1100 0011

2- L'opérateur Bitwise sur des nombres

Différentes langues peuvent avoir plusieurs types de données pour représenter des nombres.
  • Java: byte, short, int, long, double.
  • C#: byte, sbyte, short, ushort, int, uint, long, ulong, float, double
  • Javascript: double
  • .....
Javascript stocke des nombres sous forme de nombres à virgule flottante de 64 bits (64 bits floating point numbers). Mais des opérations bitwise sont effectuées sur des entiers 32 bit. D'autres langages tels que Java, C#,..  des opérations  bitwise sont également effectuées sur des entiers 32 bit.
Donc avant d'effectuer les opérateurs  bitwise avec des nombres, vous devez convertir leurs opérandes en entiers 32 bits.
Base 10 Base 2 32 bits
5 101 00000000000000000000000000000101
218 11011010 00000000000000000000000011011010
En  Javascript la méthode  toString(base) vous permet de changer n'importe quel nombre de la base 10 (base 10) à une autre base.
toString-base-example.js (Javascript)
let a = 8;


// Base 2 string.
console.log( a.toString(2) );// 1000

// Base 8 string
console.log( a.toString(8) ); // 10

// Base 16 string
console.log( a.toString(16) ); // 8


let b = 218;


// Base 2 string.
console.log( b.toString(2) );// 11011010

// Base 8 string
console.log( b.toString(8) ); // 332

// Base 16 string
console.log( b.toString(16) ); // da

 
Exemple :
Decimal Binary
5 00000000000000000000000000000101
1 00000000000000000000000000000001
5 & 1 = 1 00000000000000000000000000000001
5 | 1  = 5 00000000000000000000000000000101
5 ^ 1  = 4 00000000000000000000000000000100
~ 5    = -6 11111111111111111111111111111010
Remarque : Dans 32 bit, le premier  bit sert à déterminer le signe (sign) de nombre. Si ce  bit vaut 1 il correspond au signe ( - ), si ce  bit vaut 0 il correspond au signe ( + )

Bitwise Left Shift (<<)

Decimal Binary
5 00000000000000000000000000000101
5 << 1  = 10 00000000000000000000000000001010
5 << 2  = 20 00000000000000000000000000010100
L'opérateur  Bitwise Left Shift ( << ) peut changer le signe (sign) du nombre.
(Javascript code)
console.log( 1073741824 << 1); // -2147483648

console.log( 2684354560 << 1); // 1073741824

Bitwise Right Shift (>>)  [Unsigned Right Shift]

Decimal Binary
29 00000000000000000000000000011101
29 >> 1  = 14 00000000000000000000000000001110
29 >> 2  = 7 00000000000000000000000000000111
L'opérateur  Bitwise Right Shift ( >> ) ne change pas le signe de nombre parce que le premier  bit ne déplace pas.

Bitwise Right Shift (>>>) [Zero fill right Shift]

L'opérateur  Bitwise Right Shift ( >>> ) peut changer le signe de nombre.
(Javascript Code)
console.log( -1073741824 >>> 1); // 1610612736

console.log( 1073741824 >>> 1); // 536870912

3- À quoi sert Bitwise ?

Les calculs  bitwise sont directement soutenus par le processeur (processor) de l'ordinateur, il est très rapide. Ci-dessous, je liste quelques exemples d'utilisation de ces calculs.
Utilisez les opérateurs  bitwise sur des  String (characters) en langages  Java, C#, C/C++ ... Remarque : certains langages tels que  Javascript ne soutient pas l'opérateur  bitwise du type  String.
Convertissez une lettre majuscule (Uppercase) en lettre minuscule (Lowercase) :
// Rule: x | ' '

('A' | ' ') ==> 'a'
('B' | ' ') ==> 'b'

('a' | ' ') => 'a'
Convertissez une lettre minuscule (Lowercase) en lettre majuscule (Uppercase)  :
// Rule: x & '_'


('a' & '_') ==> 'A'
('b' & '_') ==> 'B'

('A' & '_') ==> 'A'
Renversez une lettre majuscule (Uppercase) en lettre minuscule (Lowercase), une lettre minuscule (Lowercase) en lettre majuscule (Uppercase) :
// Rule: x ^ ' '
 
('a' ^ ' ') ==> 'A'
('A' ^ ' ') ==> 'a'
Observez l'emplacement des lettres  Latin (N'applique qu'aux lettres majuscules)
// Rule:  x & '?'

'A' & '?'  ==> 1
'B' & '?'  ==> 2
...
'Z' & '?'  ==> 26

// Rule:  x ^ '@'


'A' ^ '@'  ==> 1
'B' ^ '@'  ==> 2
...
'Z' ^ '@'  ==> 26


 
Observez l'emplacement des lettres  Latin (N'applique qu'aux lettres minuscules)

// Rule:  x ^ '`'


'a' ^ '`'  ==> 1
'b' ^ '`'  ==> 2
...
'z' ^ '`'  ==> 26

// '`' : binary ( 1100000 ), hex('60'),  chr(96)
Observez l'emplacement des lettres Latin, appliquant aux lettres majuscules et aux lettres minuscules :
// Rule:  x & '\u001F'

'A' & '\u001F'  ==> 1
'B' & '\u001F'  ==> 2
...
'Z' & '\u001F'  ==> 26

'A' & '\u001F'  ==> 1
'B' & '\u001F'  ==> 2
...
'Z' & '\u001F'  ==> 26