Links- und Rechtverschiebungsoperatoren: <<
und >>
Bei den bitweisen Verschiebungsoperatoren handelt es sich um den Rechtsverschiebungsoperator (>>
), der die Bits eines Ganzzahl- oder Enumerationstypausdrucks nach rechts verschiebt, und den Linksverschiebungsoperator (<<
), der die Bits nach links verschiebt. 1
Syntax
shift-expression
:
additive-expression
shift-expression
<<
additive-expression
shift-expression
>>
additive-expression
Hinweise
Wichtig
Die folgenden Beschreibungen und Beispiele gelten unter Windows für x86- und x64-Architekturen. Die Implementierung der Links- und Rechtsverschiebungsoperatoren unterscheidet sich bei Windows für ARM-Geräte deutlich. Weitere Informationen finden Sie im Abschnitt „Shift Operators“ des Blogbeitrags Hello ARM.
Verschiebungen nach links
Der Linksverschiebungsoperator bewirkt, dass die Bits in shift-expression
um die Anzahl von Positionen nach links verschoben werden, die durch additive-expression
angegeben wird. Die durch den Verschiebevorgang frei gewordenen Bitpositionen werden mit Nullen angefüllt. Eine Verschiebung nach links ist eine logische Verschiebung (die Bits, die über das Ende hinaus verschoben werden, werden verworfen, einschließlich des Vorzeichenbits). Weitere Informationen zu den Arten von bitweisen Verschiebungen finden Sie unter Bitweises Verschieben.
Im folgenden Codebeispiel wird veranschaulicht, wie Verschiebevorgänge nach links nicht signierte Zahlen verwenden. Das folgende Beispiel veranschaulicht, was mit den Bits geschieht, indem der Wert als ein Bitset dargestellt wird. Weitere Informationen finden Sie unter bitset-Klasse.
#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
}
Wenn Sie eine signierte Zahl nach links verschieben, sodass das Vorzeichenbit davon betroffen ist, ist das Ergebnis nicht definiert. Das folgende Beispiel veranschaulicht, was geschieht, wenn ein 1-Bit nach links in die Vorzeichenbitposition verschoben wird.
#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
}
Verschiebungen nach rechts
Der Rechtsverschiebungsoperator bewirkt, dass das Bitmuster in shift-expression
um die Anzahl von Positionen nach rechts verschoben wird, die durch additive-expression
angegeben wird. Für unsignierte Zahlen werden die durch den Verschiebevorgang frei gewordenen Bitpositionen mit Nullen angefüllt. Für signierte Zahlen wird das Vorzeichenbit verwendet, um die frei gewordenen Bitpositionen zu füllen. In anderen Worten, wenn die Zahl positiv ist, wird 0 verwendet, und wenn die Zahl negativ ist, wird 1 verwendet.
Wichtig
Das Ergebnis der Verschiebung einer signierten negativen Zahl nach rechts ist implementierungsabhängig. Obwohl der Microsoft C++-Compiler das Vorzeichenbit verwendet, um frei gewordene Bitpositionen zu füllen, gibt es keine Garantie, dass auch andere Implementierungen dies tun.
Dieses Beispiel veranschaulicht, wie Verschiebevorgänge nach rechts nicht signierte Zahlen verwenden:
#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
}
Das nächste Beispiel zeigt Verschiebevorgänge nach rechts mit positiven, signierten Zahlen.
#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
}
Das nächste Beispiel zeigt Verschiebevorgänge nach rechts mit negativen, signierten Ganzzahlen.
#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
}
Verschiebungen und Höherstufungen
Die Ausdrücke auf beiden Seiten eines Schiebeoperators müssen vom Typ „Ganzzahl“ sein. Integrale Höherstufungen werden gemäß den unter Standardkonvertierungen beschriebenen Regeln durchgeführt. Der Ergebnistyp entspricht dem Typ des höhergestuften Ausdrucks shift-expression
.
Im folgenden Beispiel wird eine Variable vom Typ char
zu einem int
höhergestuft.
#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
}
Details
Das Ergebnis eines Verschiebevorgangs ist nicht definiert, wenn additive-expression
negativ ist oder wenn additive-expression
größer oder gleich der Anzahl von Bits im (höhergestuften) Ausdruck shift-expression
ist. Wenn additive-expression
gleich 0 ist, wird kein Verschiebevorgang durchgeführt.
#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)
}
Fußnoten
1 Es folgt die Beschreibung der Verschiebeoperatoren in der C++11 ISO-Spezifikation (INCITS/ISO/IEC 14882-2011[2012]), Abschnitte 5.8.2 und 5.8.3.
Der Wert von E1 << E2
ist E1
nach links verschobene E2
-Bitpositionen; frei gewordene Bitpositionen werden mit Nullen angefüllt. Wenn E1
einen vorzeichenlosen Typ hat, lautet der Ergebniswert E1 × 2E2, wobei der Modulo eins mehr reduziert wird als der Maximalwert, der im Ergebnistyp dargestellt werden kann. Wenn andernfalls E1
einen Typ mit Vorzeichen und einen nicht negativen Wert hat und E1 × 2E2 im entsprechenden vorzeichenlosen Typ des Ergebnistyps dargestellt werden kann, ist dieser in den Ergebnistyp konvertierte Wert der Ergebniswert. Andernfalls ist das Verhalten nicht definiert.
Der Wert von E1 >> E2
ist E1
nach rechts verschobene E2
-Bitpositionen. Wenn E1
einen vorzeichenlosen Typ hat oder E1
einen Typ mit Vorzeichen und einen nicht negativen Wert hat, dann ist der Ergebniswert der ganzzahlige Teil des Quotienten von E1/2E2. Wenn E1
einen signierten Typ und einen negativen Wert hat, ist der Ergebniswert durch die Implementierung definiert.
Siehe auch
Ausdrücke mit binären Operatoren
Integrierte C++-Operatoren, Rangfolge und Assoziativität
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für