Operatoren für die linke Schicht und die rechte Schicht: << und >>

Bei den Bitweise-Umschaltoperatoren handelt es sich um den Operator für die rechte Schicht (>>), der die Bits eines Ganzzahl- oder Enumerationstypausdrucks nach rechts verschiebt, und der Umschaltoperator (<<), der die Bits nach links verschiebt. 1

Syntax

shift-expression:
additive-expression
shift-expression << additive-expression
shift-expression >> additive-expression

Bemerkungen

Von Bedeutung

Die folgenden Beschreibungen und Beispiele gelten für Windows für x86- und x64-Architekturen. Die Implementierung von Operatoren für Links- und Rechtsschicht unterscheidet sich auf Windows für ARM-Geräte erheblich. Weitere Informationen finden Sie im Abschnitt "Schichtoperatoren" des Hello ARM-Blogbeitrags.

Linke Schichten

Der Operator für die linke Schicht bewirkt, dass die Bits shift-expression um die Anzahl der durch additive-expressiondie angegebenen Positionen nach links verschoben werden. Die Bitpositionen, die durch den Schichtvorgang abgeräumt wurden, sind nullgefüllt. Eine linke Schicht ist eine logische Schicht (die Bits, die vom Ende verschoben werden, werden verworfen, einschließlich des Zeichenbits). Weitere Informationen zu den Arten bitweiser Schichten finden Sie unter Bitwise-Schichten.

Das folgende Beispiel zeigt Linksverschiebungsvorgänge mit nicht signierten Zahlen. Das Beispiel zeigt, was mit den Bits geschieht, indem der Wert als Bitmenge 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 Nummer links verschieben, sodass das Zeichenbit betroffen ist, ist das Ergebnis nicht definiert. Das folgende Beispiel zeigt, was passiert, wenn ein 1 Bit links in die Bitposition des Vorzeichens 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
}

Rechte Schichten

Der Operator für die rechte Schicht bewirkt, dass das Bitmuster shift-expression um die Anzahl der durch additive-expressiondie angegebenen Positionen nach rechts verschoben wird. Bei nicht signierten Zahlen sind die Bitpositionen, die durch den Schichtvorgang leer sind, nullgefüllt. Bei signierten Nummern wird das Zeichenbit verwendet, um die geräumten Bitpositionen auszufüllen. Anders ausgedrückt: Wenn die Zahl positiv ist, wird 0 verwendet, und wenn die Zahl negativ ist, wird 1 verwendet.

Von Bedeutung

Das Ergebnis einer Rechtsverschiebung einer signierten negativen Zahl ist implementierungsabhängig. Obwohl der Microsoft C++-Compiler das Sign-Bit zum Ausfüllen leerer Bitpositionen verwendet, besteht keine Garantie dafür, dass auch andere Implementierungen dies tun.

In diesem Beispiel werden Rechtsverschiebungsvorgänge mit nicht signierten Zahlen veranschaulicht:

#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 Rechtsverschiebungsvorgänge 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 Rechtsverschiebungsvorgänge mit negativen vorzeichenbasierten 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
}

Schichten und Werbeaktionen

Die Ausdrücke auf beiden Seiten eines Schichtoperators müssen integrale Typen sein. Integrale Werbeaktionen werden gemäß den in den Standardkonvertierungen beschriebenen Regeln durchgeführt. Der Typ des Ergebnisses entspricht dem Typ des höhergestuften shift-expression.

Im folgenden Beispiel wird eine Variable vom Typ char zu einer inthö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
}

Einzelheiten

Das Ergebnis eines Schichtvorgangs ist nicht definiert, wenn additive-expression er negativ ist oder additive-expression größer oder gleich der Anzahl der Bits in der (höhergestuft) shift-expressionist. Wenn 0 ist, findet kein Schichtvorgang statt additive-expression .

#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 Schichtoperatoren in der C++11 ISO-Spezifikation (INCITS/ISO/IEC 14882-2011[2012]), Abschnitten 5.8.2 und 5.8.3.

Der Wert von E1 << E2 links E1 verschobenen E2 Bitpositionen; leere Bits sind nullgefüllt. Wenn E1 ein nicht signierter Typ vorhanden ist, lautet der Wert des Ergebnisses E1 × 2E2, reduzierter Modulo um eins mehr als der maximalwert, der im Ergebnistyp dargestellt werden kann. Andernfalls, wenn E1 ein signierter Typ und ein nicht negativer Wert vorhanden ist und E1 × 2E2 im entsprechenden nicht signierten Typ des Ergebnistyps dargestellt werden kann, ist dieser Wert, konvertiert in den Ergebnistyp, der resultierende Wert. Andernfalls ist das Verhalten nicht definiert.

Der Wert von rechts verschobenen Bitpositionen.The value of E1 >> E2 is E1 right-shifted E2 bit positions. Wenn E1 ein nicht signierter Typ vorhanden ist oder E1 ein signierter Typ und ein nicht negativer Wert vorhanden ist, ist der Wert des Ergebnisses der integrale Bestandteil des Quotienten von E1/2E2. Wenn E1 ein signierter Typ und ein negativer Wert vorhanden sind, wird der resultierende Wert implementierungsdefiniert.

Siehe auch

Ausdrücke mit binären Operatoren
Integrierte C++-Operatoren, Rangfolge und Zuordnung