Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Operatori di spostamento sinistro e destro:
Gli operatori di spostamento bit per bit sono l'operatore di spostamento a destra (>>), che sposta i bit di un'espressione di tipo integer o di enumerazione a destra e l'operatore di spostamento a sinistra (<<), che sposta i bit a sinistra.
1
Sintassi
shift-expression:
additive-expression
shift-expression
<<
additive-expression
shift-expression
>>
additive-expression
Osservazioni:
Importante
Le descrizioni e gli esempi seguenti sono validi in Windows per architetture x86 e x64. L'implementazione degli operatori di spostamento a sinistra e a destra è significativamente diversa in Windows per i dispositivi ARM. Per altre informazioni, vedere la sezione "Shift Operators" del post di blog hello ARM .
Turni a sinistra
L'operatore di spostamento a sinistra fa in modo che i bit in shift-expression vengano spostati a sinistra in base al numero di posizioni specificate da additive-expression. Le posizioni di bit che sono state liberate dall'operazione di spostamento sono piene di zero. Uno spostamento a sinistra è uno spostamento logico (i bit spostati fuori dalla fine vengono eliminati, incluso il bit del segno). Per altre informazioni sui tipi di turni bit per bit, vedere Turni bit per bit.
Nell'esempio seguente vengono illustrate le operazioni di spostamento a sinistra usando numeri senza segno. L'esempio mostra cosa accade ai bit rappresentando il valore come bitset. Per altre informazioni, vedere Classe bitset.
#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
}
Se si sposta a sinistra un numero con segno in modo che il bit del segno sia interessato, il risultato non è definito. L'esempio seguente mostra cosa accade quando un bit a 1 bit viene spostato a sinistra nella posizione del bit del segno.
#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
}
Spostamenti a destra
L'operatore di spostamento a destra fa sì che il modello di bit in shift-expression venga spostato a destra in base al numero di posizioni specificate da additive-expression. Per i numeri senza segno, le posizioni di bit liberate dall'operazione di spostamento sono piene di zero. Per i numeri con segno, il bit del segno viene usato per riempire le posizioni dei bit liberate. In altre parole, se il numero è positivo, viene usato 0 e, se il numero è negativo, viene usato 1.
Importante
Il risultato di uno spostamento destro di un numero negativo con segno è dipendente dall'implementazione. Anche se il compilatore Microsoft C++ usa il bit del segno per riempire le posizioni dei bit liberate, non c'è alcuna garanzia che anche altre implementazioni lo facciano.
Questo esempio mostra le operazioni di spostamento a destra usando numeri senza segno:
#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
}
Nell'esempio seguente vengono illustrate le operazioni di spostamento a destra con numeri con segno positivo.
#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
}
Nell'esempio seguente vengono illustrate le operazioni di spostamento a destra con numeri interi con segno negativo.
#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
}
Turni e promozioni
Le espressioni su entrambi i lati di un operatore shift devono essere tipi integrali. Le promozioni integrali vengono eseguite in base alle regole descritte in Conversioni standard. Il tipo del risultato è uguale al tipo dell'oggetto alzato shift-expressiondi livello.
Nell'esempio seguente una variabile di tipo viene alzata di livello char a .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
}
Dettagli
Il risultato di un'operazione di spostamento non è definito se additive-expression è negativo o se additive-expression è maggiore o uguale al numero di bit nell'oggetto (alzato di livello). shift-expression Non viene eseguita alcuna operazione di spostamento se additive-expression è 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)
}
Note a piè di pagina
1 Di seguito è riportata la descrizione degli operatori di spostamento nella specifica ISO C++11 (INCITS/ISO/IEC 14882-2011[2012]), sezioni 5.8.2 e 5.8.3.
Il valore di E1 << E2 è E1 posizioni di bit spostate E2 a sinistra. I bit liberati sono pieni di zero. Se E1 ha un tipo senza segno, il valore del risultato è E1 × 2E2, modulo ridotto uno più del valore massimo rappresentabile nel tipo di risultato. In caso contrario, se E1 ha un tipo con segno e un valore non negativo e E1 × 2E2 è rappresentabile nel tipo senza segno corrispondente del tipo di risultato, tale valore, convertito nel tipo di risultato, è il valore risultante; in caso contrario, il comportamento non è definito.
Il valore di E1 >> E2 è E1 posizioni di bit spostate a E2 destra. Se E1 ha un tipo senza segno o se E1 ha un tipo con segno e un valore non negativo, il valore del risultato è la parte integrante del quoziente di E1/2E2. Se E1 ha un tipo con segno e un valore negativo, il valore risultante è definito dall'implementazione.
Vedere anche
Espressioni con operatori binari
Operatori, precedenza e associatività predefiniti C++