Les opérateurs binaires ont été inclus dans le langage C pour faciliter le travail bas niveau avec les données et le matériel : configuration de registre, masquage, multiplication et division par une puissance de deux. Les règles de fonctionnement se sont établies à l'époque des processeurs 8 et 16 bits.
On se trompe souvent lors des décalages sur les types signed, car le résultat dépend de l'implémentation (décalage arithmétique ou logique), ainsi qu'en cas de dépassement de la taille du type. Les erreurs peuvent entraîner une corruption des données, des calculs incorrects et un comportement indéfini.
Décalage à gauche (<<) : équivalent à multiplier la valeur par 2 à la puissance k (a << k). Remplit toujours avec des zéros à droite.
Décalage à droite (>>) : pour une valeur unsigned, remplit à gauche avec des zéros (décalage logique), tandis que pour signed, cela peut être rempli soit avec le bit de signe (décalage arithmétique), soit avec des zéros (le comportement dépend du compilateur).
Exemple :
unsigned int x = 5; // 0000 0101 unsigned int y = x << 1; // 0000 1010 == 10 int z = -4; // 1111 1100 (si 8 bits) int w = z >> 1; // Peut rester 1111 1110 (-2) ou 0111 1110 (dépend de l'implémentation)
Caractéristiques clés :
Que se passe-t-il lors du décalage d'un nombre négatif à droite avec >> ?
Le résultat dépend de l'implémentation : c'est la plupart du temps un décalage arithmétique en conservant le signe, mais cela n'est pas garanti par la norme !
Quel est le résultat d'un décalage d'un nombre de bits supérieur à la taille du type ?
Comportement indéfini. Par exemple, 1 << 32 pour un type 32 bits peut donner n'importe quoi, voire faire planter le programme.
Peut-on utiliser des opérateurs binaires pour des nombres à virgule flottante ?
Non, les types standards float, double ne prennent pas en charge les opérations binaires. Seuls les types entiers.
Un programmeur a décalé un int de 32 pour créer un masque — sur certaines plateformes, cela conduisait à zéro, sur d'autres à une valeur non reconnaissable.
Avantages :
Inconvénients :
Au lieu de cela, des valeurs unsigned et le masquage du nombre de bits via des macros étaient utilisés, avec une documentation claire et une vérification de la longueur du type à l'aide de sizeof.
Avantages :
Inconvénients :