Bien programmer en langage C
Date de publication : 28 mai 2008
XIV. Opérateurs bit à bit
XIV-A. Description des opérateurs bits à bits
XIV-A-1. Introduction
XIV-A-2. NOT (NON)
XIV-A-3. AND (ET)
XIV-A-4. OR (OU)
XIV-A-5. XOR (OU exclusif)
XIV-A-6. SHR (Décalage à droite)
XIV-A-7. SHL (Décalage à gauche)
XIV-B. Usages des opérateurs bits à bits
XIV-B-1. Manipulations de l'état des bits d'une variable
XIV-B-1-a. Positionner un bit à 1
XIV-B-1-b. Positionner un bit à 0
XIV-B-1-c. Tester la valeur d'un bit
XIV-B-2. Conclusion
XIV. Opérateurs bit à bit
XIV-A. Description des opérateurs bits à bits
XIV-A-1. Introduction
Toute donnée informatique est stockée en mémoire sous la forme d'une combinaison de bits. Par exemple
un entier valant 10 (base 10) implémenté par une mémoire d'une largeur de 16-bit contient :
soit, en héxadécimal
Le opérateurs bits permettent de modifier et de tester un ou plusieurs bits d'une donnée. Ces opérateurs
sont :
-
NOT (NON)
-
AND (ET)
-
OR (OU)
-
XOR (OU exclusif)
-
SHR (Décalage à droite)
-
SHL (Décalage à gauche)
XIV-A-2. NOT (NON)
L'opérateur unaire NOT inverse l'état d'un bit selon le tableau suivant :
Table de vérité
NOT
L'opérateur C est ~. Il agit sur chaque bit de la valeur :
unsigned a = 1 ;
unsigned b = ~ a;
|
XIV-A-3. AND (ET)
L'opérateur binaire AND combine l'état de 2 bits selon le tableau suivant :
Table de vérité AND
A
|
B
|
A AND B
|
0
|
0
|
0
|
0
|
1
|
0
|
1
|
0
|
0
|
1
|
1
|
1
|
L'opérateur C est &. Il agit sur chaque bit de la valeur :
unsigned a = 0xF0F0 ;
unsigned b = 0x00FF ;
unsigned c = a & b;
|
XIV-A-4. OR (OU)
L'opérateur binaire OR combine l'état de 2 bits selon le tableau suivant :
Table de vérité OR
A
|
B
|
A OR B
|
0
|
0
|
0
|
0
|
1
|
1
|
1
|
0
|
1
|
1
|
1
|
1
|
L'opérateur C est |. Il agit sur chaque bit de la valeur :
unsigned a = 0xF0F0 ;
unsigned b = 0x00FF ;
unsigned c = a | b;
|
XIV-A-5. XOR (OU exclusif)
L'opérateur binaire OR combine l'état de 2 bits selon le tableau suivant :
Table de vérité XOR
A
|
B
|
A XOR B
|
0
|
0
|
0
|
0
|
1
|
1
|
1
|
0
|
1
|
1
|
1
|
0
|
L'opérateur C est ^. Il agit sur chaque bit de la valeur :
unsigned a = 0xF0F0 ;
unsigned b = 0x00FF ;
unsigned c = a ^ b;
|
XIV-A-6. SHR (Décalage à droite)
L'opérateur binaire SHR a pour opérande de gauche la valeur initiale et pour opérande de droite le nombre
de bits à décaler à droite. Les bits de poids faibles sont perdus et les bits de poids forts entrés
(à gauche) sont à 0. Ce n'est pas une rotation.
L'opérateur C est >>. Il agit sur chaque bit de la valeur :
unsigned a = 0xF0F0 ;
unsigned b = 2 ;
unsigned c = a > > b;
|
XIV-A-7. SHL (Décalage à gauche)
L'opérateur binaire SHL a pour opérande de gauche la valeur initiale et pour opérande de droite le nombre
de bits à décaler à gauche. Les bits de poids forts sont perdus et les bits de poids faibles entrés
(à droite) sont à 0. Ce n'est pas une rotation.
L'opérateur C est <<. Il agit sur chaque bit de la valeur :
unsigned a = 0xF0F0 ;
unsigned b = 2 ;
unsigned c = a < < b;
|
XIV-B. Usages des opérateurs bits à bits
XIV-B-1. Manipulations de l'état des bits d'une variable
Si la variable est entière et non signée, il est possible d'utiliser les opérateurs bits pour mettre
un ou des bits à 0 ou à 1. Les usages connus sont :
-
Compression de données.
-
Commande et état de registres matériels.
-
etc.
XIV-B-1-a. Positionner un bit à 1
Le principe est de combiner la valeur avec un masque grâce à l'opérateur OU. En effet, comme l'indique
la table de vérité, les bits à 0 du masque vont laisser la valeur initiale inchangée, alors les
bits à 1 vont s'imposer.
unsigned a = 0x000F ;
unsigned b = 0x0010 ;
unsigned c = a | b;
printf (" %04X OU %04X = %04X\n, a, b, c);
|
Pour fabriquer le masque, il suffit d'utiliser un 1 que l'on décale à gauche de la valeur correspondante
au poids du bit. Par exemple :
Bit 0 : 1u < < 0 = 0000 0000 0000 0001
Bit 2 : 1u < < 2 = 0000 0000 0000 0100
Bit 15 : 1u < < 15 = 1000 0000 0000 0000
|
Comme pour toute manipulation de bits (y compris avec des constantes), on utilise des valeurs non signées
(d'où le 'u').
XIV-B-1-b. Positionner un bit à 0
Le principe est de combiner la valeur avec un masque grâce à l'opérateur ET. En effet, comme l'indique
la table de vérité, les bits à 1 du masque vont laisser la valeur initiale inchangée, alors les
bits à 0 vont s'imposer.
unsigned a = 0x000F ;
unsigned b = 0xFFF7 ;
unsigned c = a & b;
printf (" %04X OU %04X = %04X\n, a, b, c);
|
Pour fabriquer le masque, il suffit d'utiliser un 1 que l'on décale à gauche de la valeur correspondante
au poids du bit, puis on inverse les bits avec l'opérateur NON. Par exemple :
Bit 0 : ~ (1u < < 0 ) = 1111 1111 1111 1110
Bit 2 : ~ (1u < < 2 ) = 1111 1111 1111 1011
Bit 15 : ~ (1u < < 15 ) = 0111 1111 1111 1111
|
XIV-B-1-c. Tester la valeur d'un bit
Le principe est d'évaluer le resultat entre la valeur à tester d'une part et un masque à 0, sauf le bit
à tester, avec l'opérateur AND. Les bits a 0 restent à 0. Le bit à un passe à un si la valeur
lue est 1, sinon, il reste à 0. Si le résultat est 0, le bit est donc à 0. Si il n'est pas 0,
il est à 1.
unsigned a = 0x000F ;
if (a & (1u < < 2 ))
{
puts (" bit 2 = 1 " );
}
else
{
puts (" bit 2 = 0 " );
}
a
printf (" bit 2 = %d\n, !!(a & (1u << 2)));
|
XIV-B-2. Conclusion
Je laisse au lecteur le soin de refaire ces exercices, et trouver le moyen de positionner et tester plusieurs
bits d'une même variable.
Ces
macros permettent une manipulation
aisée des bits d'un entier jusqu'à 32-bit.
Copyright © 2008 Emmanuel Delahaye.
Aucune reproduction, même partielle, ne peut être faite
de ce site ni de l'ensemble de son contenu : textes, documents, images, etc.
sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à
trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.