Opérateurs de décalage vers la gauche et vers la droite : <<
et >>
Les opérateurs de décalage au niveau du bit sont l’opérateur de décalage vers la droite (>>
), qui déplace les bits d’une expression de type entier ou énumération vers la droite, et l’opérateur de décalage vers la gauche (<<
), qui déplace les bits vers la gauche. 1
Syntaxe
shift-expression
:
additive-expression
shift-expression
<<
additive-expression
shift-expression
>>
additive-expression
Notes
Important
Les descriptions et les exemples suivants sont valides sur Windows pour les architectures x86 et x64. L’implémentation des opérateurs de décalage vers la gauche et vers la droite est très différente sur Windows pour les appareils ARM. Pour plus d’informations, consultez la section « Shift Operators » du billet de blog Hello ARM.
Décalages vers la gauche
L’opérateur de décalage vers la gauche entraîne le décalage des bits de shift-expression
vers la gauche en fonction du nombre de positions spécifié par additive-expression
. Les positions de bits qui ont été libérées par l'opération de décalage sont remplies de zéros. Un décalage vers la gauche est un décalage logique (les bits qui sont déplacés après la fin sont ignorés, y compris le bit de signe). Pour plus d’informations sur les différents genres de décalages au niveau du bit, consultez Décalages au niveau du bit.
L'exemple suivant illustre les opérations de décalage vers la gauche à l'aide de nombres non signés. L'exemple montre ce qui arrive aux bits en représentant la valeur en tant que bitset. Pour plus d’informations, consultez bitset, classe.
#include <iostream>
#include <bitset>
using namespace std;
int main() {
unsigned short short1 = 4;
bitset<16> bitset1{short1}; // the bitset representation of 4
cout << bitset1 << endl; // 0b00000000'00000100
unsigned short short2 = short1 << 1; // 4 left-shifted by 1 = 8
bitset<16> bitset2{short2};
cout << bitset2 << endl; // 0b00000000'00001000
unsigned short short3 = short1 << 2; // 4 left-shifted by 2 = 16
bitset<16> bitset3{short3};
cout << bitset3 << endl; // 0b00000000'00010000
}
Si vous décalez vers la gauche un nombre signé de manière à affecter le bit de signe, le résultat n'est pas défini. L’exemple suivant montre ce qui se passe quand un bit 1 est décalé vers la gauche à la position du bit de signe.
#include <iostream>
#include <bitset>
using namespace std;
int main() {
short short1 = 16384;
bitset<16> bitset1(short1);
cout << bitset1 << endl; // 0b01000000'00000000
short short3 = short1 << 1;
bitset<16> bitset3(short3); // 16384 left-shifted by 1 = -32768
cout << bitset3 << endl; // 0b10000000'00000000
short short4 = short1 << 14;
bitset<16> bitset4(short4); // 4 left-shifted by 14 = 0
cout << bitset4 << endl; // 0b00000000'00000000
}
Décalages vers la droite
L’opérateur de décalage vers la droite entraîne le décalage du modèle de bits de shift-expression
vers la droite en fonction du nombre de positions spécifié par additive-expression
. Pour les nombres non signés, les positions de bit qui ont été libérées par l'opération de décalage sont remplies de zéros. Pour les nombres signés, le bit de signe est utilisé pour remplir les positions de bit libérées. En d'autres termes, si le nombre est positif, 0 est utilisé, et si le nombre est négatif, 1 est utilisé.
Important
Le résultat d'un décalage vers la droite d'une nombre négatif signé dépend de l'implémentation. Bien que le compilateur Microsoft C++ utilise le bit de signe pour remplir les positions de bits vacantes, il n’existe aucune garantie que les autres implémentations le fassent également.
Cet exemple illustre les opérations de décalage vers la droite à l'aide de nombres non signés :
#include <iostream>
#include <bitset>
using namespace std;
int main() {
unsigned short short11 = 1024;
bitset<16> bitset11{short11};
cout << bitset11 << endl; // 0b00000100'00000000
unsigned short short12 = short11 >> 1; // 512
bitset<16> bitset12{short12};
cout << bitset12 << endl; // 0b00000010'00000000
unsigned short short13 = short11 >> 10; // 1
bitset<16> bitset13{short13};
cout << bitset13 << endl; // 0b00000000'00000001
unsigned short short14 = short11 >> 11; // 0
bitset<16> bitset14{short14};
cout << bitset14 << endl; // 0b00000000'00000000
}
L'exemple suivant illustre les opérations de décalage vers la droite avec des nombres positifs signés.
#include <iostream>
#include <bitset>
using namespace std;
int main() {
short short1 = 1024;
bitset<16> bitset1(short1);
cout << bitset1 << endl; // 0b00000100'00000000
short short2 = short1 >> 1; // 512
bitset<16> bitset2(short2);
cout << bitset2 << endl; // 0b00000010'00000000
short short3 = short1 >> 11; // 0
bitset<16> bitset3(short3);
cout << bitset3 << endl; // 0b00000000'00000000
}
L'exemple suivant illustre les opérations de décalage vers la droite avec des entiers négatifs signés.
#include <iostream>
#include <bitset>
using namespace std;
int main() {
short neg1 = -16;
bitset<16> bn1(neg1);
cout << bn1 << endl; // 0b11111111'11110000
short neg2 = neg1 >> 1; // -8
bitset<16> bn2(neg2);
cout << bn2 << endl; // 0b11111111'11111000
short neg3 = neg1 >> 2; // -4
bitset<16> bn3(neg3);
cout << bn3 << endl; // 0b11111111'11111100
short neg4 = neg1 >> 4; // -1
bitset<16> bn4(neg4);
cout << bn4 << endl; // 0b11111111'11111111
short neg5 = neg1 >> 5; // -1
bitset<16> bn5(neg5);
cout << bn5 << endl; // 0b11111111'11111111
}
Décalages et promotions
Les expressions des deux côtés de l'opérateur de décalage doivent être de type intégral. Les promotions de types intégraux sont effectuées en fonction des règles décrites dans Conversions standard. Le type du résultat est identique au type du shift-expression
promu.
Dans l’exemple suivant, une variable de type char
est promue en int
.
#include <iostream>
#include <typeinfo>
using namespace std;
int main() {
char char1 = 'a';
auto promoted1 = char1 << 1; // 194
cout << typeid(promoted1).name() << endl; // int
auto promoted2 = char1 << 10; // 99328
cout << typeid(promoted2).name() << endl; // int
}
Détails
Le résultat d’une opération de décalage est indéfini si additive-expression
est négatif, ou si additive-expression
est supérieur ou égal au nombre de bits dans le shift-expression
(promu). Aucune opération de décalage n’a lieu si additive-expression
a la valeur 0.
#include <iostream>
#include <bitset>
using namespace std;
int main() {
unsigned int int1 = 4;
bitset<32> b1{int1};
cout << b1 << endl; // 0b00000000'00000000'00000000'00000100
unsigned int int2 = int1 << -3; // C4293: '<<' : shift count negative or too big, undefined behavior
unsigned int int3 = int1 >> -3; // C4293: '>>' : shift count negative or too big, undefined behavior
unsigned int int4 = int1 << 32; // C4293: '<<' : shift count negative or too big, undefined behavior
unsigned int int5 = int1 >> 32; // C4293: '>>' : shift count negative or too big, undefined behavior
unsigned int int6 = int1 << 0;
bitset<32> b6{int6};
cout << b6 << endl; // 0b00000000'00000000'00000000'00000100 (no change)
}
Notes de bas de page
1 Vous trouverez ci-dessous la description des opérateurs de décalage dans la spécification ISO C++11 (INCITS/ISO/IEC 14882-2011[2012]), sections 5.8.2 et 5.8.3.
La valeur de E1 << E2
est E1
décalée vers la gauche de positions de bit E2
; les bits libérés sont remplis de zéros. Si E1
a un type non signé, le résultat est E1 × 2E2. Ce résultat est ensuite ajusté par l’opération de modulo avec la valeur maximale pouvant être représentée dans le type du résultat plus un. Sinon, si E1
a un type signé et une valeur non négative, et si E1 × 2E2 peut être représenté dans le type non signé correspondant du type du résultat, cette valeur, convertie vers le type du résultat, est la valeur résultante. Dans le cas contraire, le comportement est indéfini.
La valeur de E1 >> E2
est E1
décalée vers la droite de positions de bit E2
. Si E1
a un type non signé, ou si E1
a un type signé et une valeur non négative, la valeur du résultat est la partie de type intégral du quotient de E1/2E2. Si E1
a un type signé et une valeur négative, la valeur résultante est définie par l'implémentation.
Voir aussi
Expressions avec des opérateurs binaires
Opérateurs intégrés, priorité et associativité C++
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour