Opérations sur les bits

27 janvier 2025

Voici les principaux opérateurs binaires:

1. L’opérateur AND binaire (&)

Cet opérateur effectue une opération « ET » bit à bit entre deux entiers. Le résultat est 1 si les deux bits correspondants sont 1, sinon il est 0.

Exemple :

#include <arduino.h>
#define VITESSE_SERIAL 9600
void setup() {
    Serial.begin(VITESSE_SERIAL);
    int a = 5;   // 0101 en binaire
    int b = 3;   // 0011 en binaire
    int result = a & b;  // 0001 en binaire
    Serial.println(result);  // Affiche 1
}
void loop(){}

2. L’opérateur OR binaire (|)

Cet opérateur effectue une opération « OU » bit à bit entre deux entiers. Le résultat est 1 si au moins un des deux bits correspondants est 1, sinon il est 0.

Exemple :

#include <arduino.h>
#define VITESSE_SERIAL 9600
void setup() {
    Serial.begin(VITESSE_SERIAL);
    int a = 5;   // 0101 en binaire
    int b = 3;   // 0011 en binaire
    int result = a | b;  // 0111 en binaire
    Serial.println(result);  // Affiche 7
}
void loop(){}

3. L’opérateur XOR binaire (^)

L’opérateur « OU exclusif » effectue une opération bit à bit entre deux entiers. Le résultat est 1 si un seul des deux bits correspondants est 1, mais pas les deux.

Exemple :

#include <arduino.h>
#define VITESSE_SERIAL 9600
void setup() {
    Serial.begin(VITESSE_SERIAL);
    int a = 5;   // 0101 en binaire
    int b = 3;   // 0011 en binaire
    int result = a ^ b;  // 0110 en binaire
    Serial.println(result);  // Affiche 6
}
void loop(){}

4. L’opérateur NOT binaire (~)

Cet opérateur effectue une inversion de tous les bits de l’entier. Tous les 1 deviennent des 0 et tous les 0 deviennent des 1.

Exemple :

#include <arduino.h>
#define VITESSE_SERIAL 9600
void setup() {
    Serial.begin(VITESSE_SERIAL);
    int a = 5;   // 0101 en binaire
    int result = ~a;  // 1010 en binaire (en représentation complément à deux)
    Serial.println(result);  // Affiche -6 (en complément à deux)
}
void loop(){}

Table de vérité des opérateurs

.


5. Les opérateurs de décalage (<< et >>)

Exemple :

#include <arduino.h>
#define VITESSE_SERIAL 9600
void setup() {
    Serial.begin(VITESSE_SERIAL);
    int a = 5;   // 0101 en binaire
    int left_shift = a << 1;  // Décalage à gauche : 1010 en binaire (10 en décimal)
    int right_shift = a >> 1; // Décalage à droite : 0010 en binaire (2 en décimal)

    Serial.print("Décalage à gauche : "); Serial.println(left_shift);  // Affiche 10
    Serial.print("Décalage à droite : "); Serial.println(right_shift); // Affiche 2
}
void loop(){}

Résumé des opérateurs de bits :

OpérateurSignificationExemple avec a = 5 et b = 3
&AND bit à bita & b = 1
|OR bit à bita | b = 7
^XOR bit à bita ^ b = 6
~NOT (inversion des bits)~a = -6
<<Décalage à gauchea << 1 = 10
>>Décalage à droitea >> 1 = 2

Ces opérateurs sont puissants pour manipuler directement les bits dans les programmes C, ce qui est utile dans des domaines comme la programmation système, les systèmes embarqués, ou les calculs de bas niveau.


Prenons la valeur binaire 0b10011011:

Conversion vers la base 10 (décimal)



/*
  Projet: Opérations sur les bits
  Pour:   Le cours 420-1C4-JR: Objets connectés
  Auteur: Alain Boudreault (aka VE2CUY)
  Date:   2025.01.27
  --------------------------------------------------------------------
  Description:

    Expérimentation avec les opérateurs au niveau des bits; 
      & , | , ~ , ^ , << et >> .

  PlatformIO:

    Rappel: ctrl+alt+b = build
            ctrl+alt+u = upload
            ctrl+alt+s = serial terminal
  --------------------------------------------------------------------
  M-A-J:

  --------------------------------------------------------------------
  NOTE: Sous platformio, monitor_speed = 115200

*/

// Les déclarations
#include <projet.h>
void afficherBinaire(int nombre, byte nbBits = 8, bool ln = true);

// Début du programme
void setup() {
  Serial.begin(VITESSE_SERIAL);
    while (!Serial) {
    ; // Attendre que le port série soit connecté.
  }
  Serial.println(F("----> Début du programme\n"));
  
  // Exemple d'affichage en binaire
  exempleCompterBinaire();

  // Exemple de permutations de bits
  //shiftGauche();
  //shiftDroite();
  
  // Exemple d'opérations logiques sur les bits
  //exempleOp(AND);
  //exempleOp(OR);
  //exempleOp(XOR);
  //exempleOp(NOT); 

  // Afficher des nombres négatifs en binaire
  //exempleNegatif();

} // setup()

void loop() { // Rien à faire ici ...
}


// Implémentation des fonctions
//=================================================================
void shiftGauche(void) {
  byte nombre = 0b00000001;
  Serial.println(F("\n------------------------------------------------------------------")); 
  Serial.println(F("Démonstration d'une permutation vers la gauche avec l'opérateur << \n\n76543210\n--------"));
  afficherBinaire(nombre);
  for (int n = 1 ; n <= 7; n++) {
    afficherBinaire(nombre << n);
  }
} // shiftGauche()

//=================================================================
void shiftDroite(void) {
  Serial.println(F("\n------------------------------------------------------------------")); 
  Serial.println(F("Démonstration d'une permutation vers la droite avec l'opérateur >> \n\n76543210\n--------"));
  byte nombre = 0b10000000;
  afficherBinaire(nombre);
  for (int n = 1 ; n <= 7; n++) {
    afficherBinaire(nombre >> n);
  }
} // shiftDroite()


//=================================================================
void exempleOp(operateurBinaire op){
    
    int a         = 5;      // 0101 en binaire
    int b         = 3;      // 0011 en binaire
    int resultat  = 0;
    String strOp[]  = {"a & b", "a | b", "a ^ b ", "~a"};

    Serial.println(F("\n------------------------------------"));  
    Serial.print(F("Démonstration de "));
    Serial.print(strOp[op]);
    Serial.println(F("\n\n76543210\n--------"));  

    switch (op) {
    case AND:
      resultat  = a & b;  // // 0001 en binaire
      break;
    case OR:
      resultat  = a | b; 
      break;
    case XOR:
      resultat  = a ^ b; 
      break;
    case NOT:
      resultat  = ~a; 
      break;
    default:
      break;
    }

    afficherBinaire(a);
    if (op != NOT) afficherBinaire(b);
    afficherBinaire(resultat);  // Affiche 1
} // exempleOp()


//=================================================================
// Voici un exemple simplifié de exempleOp
void exempleAnd(void){
    Serial.println(F("\n------------------------------------"));  
    Serial.println(F("Démonstration de a & b\n\n76543210\n--------"));  
    int a         = 5;      // 0101 en binaire
    int b         = 3;      // 0011 en binaire
    int resultat  = a & b;  // 0001 en binaire
    afficherBinaire(a);
    afficherBinaire(b);
    afficherBinaire(resultat);  // Affiche 1
} //exempleAnd()

//=================================================================
void afficherBinaire(int nombre, byte nbBits, bool ln) {
  // NOTE: Utilisation des opérateurs sur les bits (>> et &)
  // pour afficher le nombre en format binaire.
  for (int i = nbBits - 1; i >= 0; i--) {
    Serial.print((nombre >> i) & 1); 
  }
  if (ln) Serial.println();
} // afficherBinaire

//=================================================================
void exempleNegatif(){
    // Afficher un nombre négatif en binaire:
    // Voir: https://fr.wikipedia.org/wiki/Compl%C3%A9ment_%C3%A0_deux
  Serial.println(F("\n------------------------------------"));  
  for (int i = -5; i < 1 ; i++) {  
  Serial.print(F("\nAffichage de : "));
    Serial.println(i);  
    afficherBinaire(i, 32);
  }
} // exempleNegatif()

//=================================================================
void exempleCompterBinaire() {
    // Compter en binaire (base 2)
    Serial.println("\n---------------------------------------"); 
    Serial.println("Démonstration d'un affichage en binaire\n\n8421\n3210\n----");
  for (int i=0; i<= 0b1111; i++) {
      afficherBinaire(i,4);
      delay(SECONDE/2);
  }
} //exempleCompterBinaire()

// FIN DU PROGRAMME

Fichier projet.h

#ifndef projet_h
#define projet_h

#include <arduino.h>
#define VITESSE_SERIAL  115200
#define SECONDE         1000
enum operateurBinaire {
    AND,    // &
    OR,     // |
    XOR,    // ^
    NOT,    // ~
    GAUCHE, // <<
    DROITE  // >>
};

// NOTE: Valeur par défaut seulement dans le prototype, pas dans l'implémentation
void shiftGauche(void);
void shiftDroite(void);
void exempleOp(operateurBinaire op);
void exempleNegatif();
void exempleCompterBinaire();
#endif