Операторы смены влево и вправо: <<
>>
Побитовые операторы shift — это оператор shift вправо (>>
), который перемещает биты целочисленного или перечисления выражения типа вправо, а оператор слева<<
— влево, который перемещает биты влево. 1
Синтаксис
shift-expression
:
additive-expression
shift-expression
<<
additive-expression
shift-expression
>>
additive-expression
Замечания
Внимание
В Windows для архитектур x86 и x64 допустимы следующие описания и примеры. Реализация операторов влево и вправо значительно отличается в Windows для устройств ARM. Дополнительные сведения см. в разделе "Операторы shift" записи блога Hello ARM .
Сдвиги влево
Оператор shift влево приводит к перемещению битов влево shift-expression
налево по количеству позиций, заданных additive-expression
. Позиции битов, освобожденные при операции сдвига, заполняются нулями. Сдвиг влево является логическим сдвигом (биты, сдвигаемые с конца отбрасываются, включая бит знака). Дополнительные сведения о типах побитовых сдвигов см. в разделе "Побитовые сдвиги".
В следующем примере показаны операции сдвига влево с использованием чисел без знака. В этом примере показано, что происходит с битами при представлении значения как bitset. Дополнительные сведения см . в классе 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
}
Если выполняется сдвиг влево числа со знаком и при этом затрагивается бит знака, результат не определен. В следующем примере показано, что происходит при перемещении 1 бита в положение бита знака.
#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
}
Сдвиги вправо
Оператор shift вправо shift-expression
приводит к перемещению битового шаблона вправо по количеству позиций, заданных .additive-expression
Для чисел без знака позиции битов, освобожденные при операции сдвига, заполняются нулями. Для чисел со знаком бит знака используется для заполнения освобожденных позиций битов. Другими словами, если число является положительным, используется 0, если число является отрицательным, используется 1.
Внимание
Результат сдвига вправо отрицательного числа со знаком зависит от реализации. Хотя компилятор Microsoft C++ использует бит знака для заполнения освобожденных битовых позиций, нет никаких гарантий, что другие реализации также делают это.
В следующем примере показаны операции сдвига вправо с использованием чисел без знака.
#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
}
В следующем примере показаны операции сдвига вправо с использованием положительных чисел со знаком.
#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
}
В следующем примере показаны операции сдвига вправо с использованием отрицательных целых чисел со знаком.
#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
}
Смены и рекламные акции
Выражения с обеих сторон оператора сдвига должны быть целочисленными типами. Целочисленные рекламные акции выполняются в соответствии с правилами, описанными в разделе "Стандартные преобразования". Тип результата совпадает с типом повышенного shift-expression
уровня.
В следующем примере переменная типа char
повышается до типа 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
}
Сведения
Результат операции смены не определен, если additive-expression
отрицательный или additive-expression
больше или равен количеству битов в (повышено). shift-expression
Если значение равно 0, операция смены не выполняется additive-expression
.
#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)
}
Сноски
1 Ниже описаны операторы смены в спецификации ISO C++11 (INCITS/ISO/IEC 14882-2011[2012]), разделы 5.8.2 и 5.8.3.
Значение E1 << E2
представляет собой E1
со сдвигом влево на E2
позиций битов; освобожденные биты заполняются нулями. Если E1
имеется неподписанный тип, значение результата — E1 × 2 E2, сокращенное модуло еще больше, чем максимальное значение, представляющееся в типе результата. В противном случае, если E1
имеется подписанный тип и неотрицательное значение, а E1 × 2 E2 представляется в соответствующем неподписанном типе типа результата, то это значение, преобразованное в тип результата, является результирующий значение; в противном случае поведение не определено.
Значение E1 >> E2
представляет собой E1
со сдвигом вправо на E2
позиций битов. Если E1
имеет тип без знака или E1
имеет подписанный тип и неотрицательное значение, значение результата является неотъемлемой частью кворента E1/2 E2. Если E1
имеет тип со знаком и отрицательное значение, значение результата определяется реализацией.
См. также
Выражения с двоичными операторами
Встроенные операторы C++, приоритет и ассоциативность
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по