Sdílet prostřednictvím


Operátor posunu vlevo a vpravo (>> a <<)

Bitové operátory posunutí jsou operátor pravého posunutí (>>), který přesune bity shift_expression doprava, a operátor levého posunutí (<<), který přesune bity shift_expression doleva.1

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

Poznámky

Důležitá poznámkaDůležité

Následující popisy a příklady platí v systému Windows pro architektury X86 a x64.Implementace operátorů levého a pravého posunutí se výrazně liší v zařízeních se systémem Windows RT a v zařízeních ARM.Další informace naleznete v části "Operátory posunutí" Ahoj, ty jsi ARM příspěvku blogu.

Posun doleva

Operátor levého posunutí způsobí posunutí bitů v shift-expression doleva o počet pozic určený additive-expression.Bitové pozice uvolněné operací posunutí se vyplní nulami.Posun doleva je logický posun (bity posunuté za konec se odstraní, včetně bitu znaku),Další informace o možnostech bitová posuny naleznete v tématu bitová posuny.

Následující příklad ukazuje operace levého posunutí pomocí čísel bez znaménka.Příklad ukazuje, co se děje s bity, znázorněním hodnoty jako bitové sady.Další informace naleznete v tématu bitset – třída.

#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;  // 0000000000000100

    unsigned short short2 = short1 << 1;     // 4 left-shifted by 1 = 8
    bitset<16> bitset2{short2};
    cout << bitset2 << endl;  // 0000000000001000

    unsigned short short3 = short1 << 2;     // 4 left-shifted by 2 = 16
    bitset<16> bitset3{short3};
    cout << bitset3 << endl;  // 0000000000010000
}

Pokud posunete doleva číslo se znaménkem tak, aby to mělo vliv na znaménko, bude výsledek nedefinovaný.Následující příklad ukazuje, co se stane v jazyce Visual C++, když se 1 bit posune doleva na pozici bitu znaménka.

#include <iostream>
#include <bitset>
using namespace std;

int main() {
    short short1 = 16384;    
    bitset<16> bitset1{short2};
    cout << bitset1 << endl;  // 0100000000000000 

    short short3 = short1 << 1;
    bitset<16> bitset3{short3};  // 16384 left-shifted by 1 = -32768
    cout << bitset3 << endl;  // 100000000000000
 
    short short4 = short1 << 14;
    bitset<16> bitset4{short4};  // 4 left-shifted by 14 = 0
    cout << bitset4 << endl;  // 000000000000000  
}

Posuny doprava

Operátor pravého posunutí způsobí posunutí bitů v shift-expression doprava o počet pozic určený additive-expression.V případě čísel bez znaménka se bitové pozice uvolněné operací posunutí vyplní nulami.U čísel se znaménkem se bit znaménka použije k vyplnění uvolněných bitových pozic.Platí tedy, že pokud je číslo kladné, použije se 0. Pokud je číslo záporné, použije se 1.

Důležitá poznámkaDůležité

Výsledek posunu záporného čísla se znaménkem doprava je závislý na implementaci.Přestože jazyk Visual C++ používá bit znaménka k vyplnění uvolněných pozic, není nijak zaručeno, že tak budou činit i další implementace.

Tento příklad ukazuje operace pravého posunutí pomocí čísel bez znaménka:

#include <iostream>
#include <bitset>
using namespace std;

int main() {
    unsigned short short11 = 1024;
    bitset<16> bitset11{short11};
    cout << bitset11 << endl;     // 0000010000000000

    unsigned short short12 = short11 >> 1;  // 512
    bitset<16> bitset12{short12};
    cout << bitset12 << endl;      // 0000010000000000

    unsigned short short13 = short11 >> 10;  // 1
    bitset<16> bitset13{short13};
    cout << bitset13 << endl;      // 0000000000000001

    nsigned short short14 = short11 >> 11;  // 0
    bitset<16> bitset14{short14};
    cout << bitset14 << endl;     // 0000000000000000}
}

Další příklad ukazuje operace pravého posunutí pomocí čísel s kladným znaménkem.

#include <iostream>
#include <bitset>
using namespace std;

int main() {
    short short1 = 1024;
    bitset<16> bitset1{short1};
    cout << bitset1 << endl;     // 0000010000000000

    short short2 = short1 >> 1;  // 512
    bitset<16> bitset2{short2};
    cout << bitset2 << endl;      // 0000010000000000

    short short3 = short1 >> 11;  // 0
    bitset<16> bitset3{short3};   
    cout << bitset3 << endl;     // 0000000000000000
}

Další příklad ukazuje operace pravého posunutí pomocí celých čísel se záporným znaménkem.

#include <iostream>
#include <bitset>
using namespace std;

int main() {
    short neg1 = -16;
    bitset<16> bn1{neg1};
    cout << bn1 << endl;  // 1111111111110000

    short neg2 = neg1 >> 1; // -8
    bitset<16> bn2{neg2};
    cout << bn2 << endl;  // 1111111111111000

    short neg3 = neg1 >> 2; // -4
    bitset<16> bn3{neg3};
    cout << bn3 << endl;  // 1111111111111100

    short neg4 = neg1 >> 4; // -1
    bitset<16> bn4{neg4};    
    cout << bn4 << endl;  // 1111111111111111

    short neg5 = neg1 >> 5; // -1 
    bitset<16> bn5{neg5};    
    cout << bn5 << endl;  // 1111111111111111
}

Posunutí a propagace

Výrazy na obou stranách operátoru posunutí musí být integrální typy.Integrální propagace se provádí dle pravidel popsaných v tématu Zvýšení úrovně celého čísla.Typ výsledku je stejný jako typ zvýšeného parametru shift-expression.

V následujícím příkladu je proměnná typu char povýšena na 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
}

Další podrobnosti

Výsledek operace posunutí není definován, pokud additive-expression je záporné nebo pokud additive-expression je větší nebo roven počtu bitů ve (zvýšeném) výrazu shift-expression.Operace posunutí se neprovádí, pokud additive-expression je 0.

#include <iostream>
#include <bitset>
using namespace std;

int main() {
    unsigned int int1 = 4;
    bitset<32> b1{int1};
    cout << b1 << endl;    // 00000000000000000000000000000100

    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;    // 00000000000000000000000000000100 (no change)}
}

Poznámky pod čarou

1 Následuje popis operátorů posunutí ve specifikaci C++ ISO (INCITS/ISO/IEC 14882-2011[2012]), oddíly 5.8.2 a 5.8.3.

Hodnota E1 << E2 je E1 posunuta doleva o E2 bitových pozic; uvolněné bitové pozice jsou vyplněny nulami.Pokud má E1 typ bez znaménka, hodnota výsledku je E1 × 2E2, snížené modulo o jedno více než je maximální hodnota reprezentovatelná v typu výsledku.Jinak pokud E1 má typ se znaménkem a nezápornou hodnotu a E1 × 2E2 je reprezentovatelné v odpovídajícím typu bez znaménka typu výsledku, hodnota převedená na typ výsledku je výsledná hodnota; v opačném případě je chování nedefinované.

Hodnota E1 >> E2 je posunuta doprava E1 o E2 bitových pozic.Pokud E1 má hodnotu bez znaménka nebo pokud E1 má typ se znaménkem a nezápornou hodnotu, hodnota výsledku je integrální část kvocientu E1/2E2.Pokud E1 má typ se znaménkem a zápornou hodnotu, je výsledná hodnota definovaná implementací.

Viz také

Referenční dokumentace

Výrazy s binárními operátory

Operátory C++, priorita a asociativita