Condividi tramite


Operatori Left Shift e Right Shift (>> e <<)

Gli operatori di spostamento bit per bit sono l'operatore di spostamento a destra (>>), che sposta i bit di shift_expression a destra e l'operatore di spostamento a sinistra (<<), che sposta i bit di shift_expression a sinistra. 1

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

Note

Importante

Le descrizioni e gli esempi seguenti sono validi per le architetture Windows X86 e x64.L'implementazione degli operatori di spostamento a sinistra e a destra è sostanzialmente diversa in Windows RT per i dispositivi ARM.Per altre informazioni vedere la sezione dedicata agli operatori di spostamento del post di blog introduttivo su ARM.

Spostamenti a sinistra

L'operatore di spostamento a sinistra consente di spostare a sinistra i bit di shift-expression del numero di posizioni specificato da additive-expression. Le posizioni dei bit liberate dall'operazione di spostamento vengono riempite con zero. Uno spostamento a sinistra è uno spostamento logico (i bit spostati oltre la fine vengono eliminati, incluso il bit di segno). Per altre informazioni sui tipi di spostamento bit per bit, vedere Operazione bit a bit.

Nell'esempio seguente vengono illustrate operazioni di spostamento a sinistra tramite numeri senza segno. Viene mostrato ciò che accade ai bit che rappresentano 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;  // 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
}

Se si sposta a sinistra un numero con segno coinvolgendo il bit di segno, il risultato sarà indefinito. Nell'esempio seguente viene illustrato ciò che accade in Visual C++ quando un bit viene spostato a sinistra nella posizione del bit di segno.

#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  
}

Spostamenti a destra

L'operatore di spostamento a destra consente di spostare a destra lo schema di bit di shift-expression del numero di posizioni specificato da additive-expression. Per i numeri senza segno, le posizioni dei bit liberate dall'operazione di spostamento vengono riempite con zero. Per i numeri con segno, il bit di segno viene utilizzato per riempire le posizioni dei bit liberate. In altre parole, se il numero è positivo, si utilizza 0, se il numero è negativo, si utilizza 1.

Importante

Il risultato di uno spostamento a destra di un numero negativo con segno è dipendente dall'implementazione.Sebbene Visual C++ utilizzi il bit di segno per riempile le posizioni dei bit liberate, non vi è garanzia che anche altre implementazioni facciano lo stesso.

Nell'esempio seguente vengono illustrate operazioni di spostamento a destra tramite numeri senza segno:

#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}
}

Nell'esempio seguente vengono illustrate operazioni di spostamento a destra tramite numeri con segno positivi.

#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
}

Nell'esempio seguente vengono illustrate operazioni di spostamento a destra tramite numeri interi con segno negativi.

#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
}

Spostamenti e promozioni

Le espressioni su entrambi i lati di un operatore di spostamento devono essere tipi integrali. Le promozioni integrali vengono eseguite in base alle regole descritte in Promozioni a intero. Il tipo del risultato corrisponde al tipo dell'elemento shift-expression promosso.

Nell'esempio seguente una variabile di tipo char viene promossa in un elemento 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
}

Ulteriori informazioni

Il risultato di un'operazione di spostamento è indefinito se additive-expression è negativo o se additive-expression è maggiore o uguale al numero di bit nell'elemento shift-expression promosso. 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;    // 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)}
}

Note a piè di pagina

1 Di seguito è riportata la descrizione degli operatori di spostamento nella specifica ISO C++ (INCITS/ISO/IEC 14882-2011[2012]), sezioni 5.8.2 e 5.8.3.

Il valore di E1 << E2 è E1 spostato a sinistra di E2 posizioni di bit. I bit vuoti vengono riempiti con zero. Se E1 dispone di un tipo unsigned, il valore del risultato sarà E1 × 2E2, modulo ridotto uno oltre il valore massimo rappresentabile nel tipo di risultato. In caso contrario, se E1 dispone di un tipo signed e di un valore non negativo e E1 × 2E2 è rappresentabile nel tipo unsigned corrispondente del tipo di risultato, tale valore, convertito nel tipo di risultato, sarà il valore risultante; in caso contrario, il comportamento sarà indefinito.

Il valore di E1 >> E2 è E1 spostato a destra di E2 posizioni di bit. Se E1 dispone di un tipo unsigned o se E1 dispone di un tipo signed e di un valore non negativo, il valore del risultato sarà parte integrante del quoziente di E1/2E2. Se E1 dispone di un tipo signed e di un valore negativo, il valore risultante sarà definito dall'implementazione.

Vedere anche

Riferimenti

Espressioni con operatori binari

Operatori C++, precedenza e associazione