왼쪽 시프트 및 오른쪽 시프트 연산자:
비트 시프트 연산자는 정수 또는 열거형 형식 식의 비트를 오른쪽으로 이동하는 오른쪽 시프트 연산자(>>)와 비트를 왼쪽으로 이동하는 왼쪽 시프트 연산자(<<)입니다.
1
문법
shift-expression:
additive-expression
shift-expression
<<
additive-expression
shift-expression
>>
additive-expression
비고
중요합니다
다음 설명 및 예제는 x86 및 x64 아키텍처용 Windows에서 유효합니다. ARM 디바이스용 Windows에서는 왼쪽 시프트 및 오른쪽 시프트 연산자의 구현이 크게 다릅니다. 자세한 내용은 Hello ARM 블로그 게시물의 "Shift Operators" 섹션을 참조하세요.
왼쪽 시프트
왼쪽 시프트 연산자를 사용하면 지정된 위치 additive-expression수만큼 비트 shift-expression 가 왼쪽으로 이동됩니다. 시프트 작업으로 비워진 비트 위치는 0으로 채워집니다. 왼쪽 시프트는 논리적 시프트입니다(부호 비트를 포함하여 끝에서 이동된 비트는 삭제됨). 비트 시프트의 종류에 대한 자세한 내용은 비트 시프트를 참조하세요.
다음 예제에서는 부호 없는 숫자를 사용하는 왼쪽 시프트 작업을 보여 줍니다. 이 예제에서는 값을 비트 세트로 표시하여 비트에 어떤 일이 발생하는지 보여 줍니다. 자세한 내용은 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-expression 이 지정된 위치 additive-expression수만큼 오른쪽으로 이동됩니다. 부호 없는 숫자의 경우 시프트 작업으로 비워진 비트 위치는 0으로 채워집니다. 부호 있는 숫자의 경우 부호 비트는 비워진 비트 위치를 채우는 데 사용됩니다. 즉, 숫자가 양수이면 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
}
세부 정보
시프트 작업의 결과는 음수이거나 (승격됨)shift-expression의 비트 수보다 크거나 같은 경우 additive-expression 정의 additive-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 다음은 C++11 ISO 사양(INCITS/ISO/IEC 14882-2011[2012]), 섹션 5.8.2 및 5.8.3의 교대 근무 연산자 설명입니다.
값 E1 << E2 은 왼쪽 이동 비트 E2 위치이고 E1 비워진 비트는 0으로 채워집니다. 부호 없는 형식이 있는 경우 E1 결과 값은 E1 × 2E2이며, 모듈로는 결과 형식에서 나타낼 수 있는 최대값보다 한 개 더 줄어듭니다. 그렇지 않으면 부호 있는 형식과 음수가 아닌 값이 있고 E1 × 2E2가 결과 형식의 해당 서명되지 않은 형식으로 표시될 수 있는 경우 E1 결과 형식으로 변환된 해당 값이 결과 값이고, 그렇지 않으면 동작이 정의되지 않습니다.
값 E1 >> E2 은 E1 오른쪽 이동 비트 E2 위치입니다. 부호 없는 형식이 있거나 부호 있는 형식과 음수가 아닌 값이 있는 경우 E1E1 결과 값은 E1/2E2 몫의 정수 부분입니다. 부가 형식과 음수 값이 있는 경우 E1 결과 값은 구현에서 정의됩니다.