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é |
---|
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é |
---|
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í.