Utiliser les opérations de décalage de bit en C

Jinku Hu 12 octobre 2023
  1. Utiliser l’opérateur << pour décaler le nombre vers la gauche en C
  2. Utiliser le décalage à gauche de l’entier multiple par deux en C
  3. Décalage vers la droite - Différence de décalage arithmétique et logique en C
Utiliser les opérations de décalage de bit en C

Cet article explique plusieurs méthodes d’utilisation des opérations de décalage de bits en C.

Utiliser l’opérateur << pour décaler le nombre vers la gauche en C

Les opérations de décalage binaire font partie de tout langage de programmation et repositionnent chaque bit d’un opérande entier selon le nombre de positions spécifié. Pour mieux démontrer les effets de ces opérations, nous avons inclus dans les exemples suivants la fonction appelée binary qui imprime la représentation binaire de l’entier donné. Notez que cette fonction n’est implémentée que pour travailler avec des valeurs entières de 32 bits. L’exemple de code suivant démontre le décalage à gauche de deux positions et affiche les représentations des nombres en conséquence.

#include <stdio.h>
#include <stdlib.h>

void binary(unsigned n) {
  unsigned i;
  for (i = 1 << 31; i > 0; i /= 2) (n & i) ? printf("1") : printf("0");
}

int main(int argc, char *argv[]) {
  int n1 = 123;

  binary(n1);
  printf(" : %d\n", n1);
  n1 <<= 2;
  binary(n1);
  printf(" : %d\n", n1);

  exit(EXIT_SUCCESS);
}

Production :

00000000000000000000000001111011 : 123
00000000000000000000000111101100 : 492

Utiliser le décalage à gauche de l’entier multiple par deux en C

Nous pouvons utiliser l’opération de décalage à gauche pour mettre en œuvre la multiplication par deux, ce qui peut être plus efficace sur le matériel. Notez que lors du décalage vers la gauche, il n’y a pas de différence entre le décalage arithmétique et le décalage logique. Le décalage d’une seule position pour un entier donné entraîne une multiplication ; nous pouvons donc nous décaler davantage pour obtenir la multiplication en conséquence.

#include <stdio.h>
#include <stdlib.h>

void binary(unsigned n) {
  unsigned i;
  for (i = 1 << 31; i > 0; i /= 2) (n & i) ? printf("1") : printf("0");
}

int main(int argc, char *argv[]) {
  int n1 = 123;

  printf("%d\n", n1);
  n1 <<= 1;
  printf("%d x2\n", n1);

  exit(EXIT_SUCCESS);
}

Production :

492
984 x2

Décalage vers la droite - Différence de décalage arithmétique et logique en C

Il convient de mentionner que les entiers signés et non signés sont représentés différemment sous le capot. En d’autres termes, les entiers signés sont implémentés comme des valeurs complémentaires de deux. En conséquence, le bit le plus significatif des nombres négatifs est appelé 1, alors que les entiers positifs commencent par 0 comme d’habitude. Ainsi, lorsque nous déplaçons les nombres négatifs vers la droite logiquement, nous perdons leur signe et obtenons l’entier positif. Nous devons donc différencier les décalages logiques et arithmétiques, ce dernier préservant le bit le plus significatif. Même s’il y a une différence entre les concepts, C ne fournit pas d’opérateurs séparés. De plus, la norme C ne spécifie pas le comportement, tel qu’il est défini par l’implémentation matérielle. Comme le montre l’exemple de sortie suivant, la machine sous-jacente effectue le décalage arithmétique et préserve la valeur négative de l’entier.

#include <stdio.h>
#include <stdlib.h>

void binary(unsigned n) {
  unsigned i;
  for (i = 1 << 31; i > 0; i /= 2) (n & i) ? printf("1") : printf("0");
}

int main(int argc, char *argv[]) {
  int n2 = -24;

  binary(n2);
  printf(" : %d\n", n2);
  n2 >>= 3;
  binary(n2);
  printf(" : %d\n", n2);

  exit(EXIT_SUCCESS);
}

Production :

11111111111111111111111111101000 : -24
11111111111111111111111111111101 : -3
Auteur: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook