Partilhar via


Operadores de deslocamento à esquerda e deslocamento à direita (>> e <<)

Os operadores shift bit a bit são o operador shift para a direita (>>), que move os bits da shift_expression para a direita, e o operador shift para a esquerda (<<), que move os bits da shift_expression para a esquerda. 1

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

Comentários

Importante

As descrições e exemplos a seguir são válidos no Windows para arquiteturas X86 e x64.A implementação de operadores shift para a esquerda e direita é significativamente diferente no Windows RT para dispositivos ARM.Para obter mais informações, consulte a seção sobre “operadores shift” na publicação do blog Hello ARM.

Deslocamentos para a esquerda

O operador shift para a esquerda faz com que os bits na shift-expression sejam deslocados para a esquerda pelo número de posições especificadas pela additive-expression. As posições de bits que foram liberadas pela operação de deslocamento são preenchidas com zeros. Um deslocamento para a esquerda é um deslocamento lógico (os bits que são deslocados da extremidade são descartados, incluindo o bit de sinal). Para obter mais informações sobre os tipos de operadores bit a bit, consulte o artigo Shift (deslocamento de bits).

O exemplo a seguir mostra operações de deslocamento para a esquerda usando números sem sinal. O exemplo a seguir mostra o que está acontecendo com os bit representando o valor como um conjunto de bits. Para obter mais informações, consulte 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 você deslocar um número com sinal para a esquerda de forma que o bit de sinal seja afetado, o resultado será indefinido. O exemplo a seguir mostra o que acontece no Visual C++ quando 1 bit é deslocado para a esquerda na posição de bit de sinal.

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

Deslocamentos para a direita

O operador shift para a direita faz com que o padrão de bits na shift-expression seja deslocado para a direita pelo número de posições especificadas pela additive-expression. Para números sem sinal, as posições de bits que foram liberadas pela operação de deslocamento são preenchidas com zeros. Para números com sinal, o bit de sinal é usado para preencher as posições de bit vagas. Ou seja, se o número for positivo, 0 será usado, e se o número for negativo, 1 será usado.

Importante

O resultado do deslocamento de um número negativo para a direita dependerá da implementação.Embora o Visual C++ use o bit de sinal para preencher as posições de bits vagas, não há garantia de que outras implementações também façam isso.

Este exemplo mostra operações de deslocamento para a direita usando números sem sinal:

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

O próximo exemplo mostra operações de deslocamento para a direita com números positivos com sinal.

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

O próximo exemplo mostra operações de deslocamento para a direita com inteiros negativos com sinal.

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

Deslocamentos e promoções

As expressões em ambos os lados do operador shift devem ser tipos integrais. As promoções integrais são executadas de acordo com as regras descritas em Promoções integrais. O tipo do resultado é o mesmo tipo da shift-expression promovida.

No exemplo a seguir, uma variável de tipo char é promovida 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
}

Detalhes adicionais

O resultado de uma operação de deslocamento é indefinido quando a additive-expression é negativa, ou se a additive-expression for maior ou igual ao número de bits da shift-expression (promovida). Nenhuma operação de deslocamento é executada quando a 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)}
}

Notas de rodapé

1 Esta é a descrição dos operadores shift da especificação C++ ISO (INCITS/ISO/IEC 14882-2011 [2012]), nas seções 5.8.2 e 5.8.3.

O valor de E1 << E2 é E1 deslocado para a esquerda nas posições do bit E2; os bits vagos são preenchidos por zero. Se E1 tiver um tipo sem sinal, o valor do resultado será E1 × 2E2, módulo reduzido uma vez mais que o valor máximo representável no tipo de resultado. Caso contrário, se E1 tiver um tipo com sinal e um valor positivo, e E1 × 2E2 for representável no tipo sem sinal correspondente do tipo de resultado, esse valor, convertido no tipo de resultado, será o valor resultante; caso contrário, o comportamento será indefinido.

O valor de E1 >> E2 é E1 é deslocado para a direita nas posições do bit E2. Se E1 tiver um tipo sem sinal ou se E1 tiver um tipo com sinal e um valor positivo, o valor do resultado será a parte integral do quociente de E1/2E2. Se E1 tiver um tipo com sinal e um valor negativo, o valor resultante será definido pela implementação.

Consulte também

Referência

Expressões com operadores binários

Operadores, precedência e associatividade C++