연산자 | 기호 | 설명 |
---|---|---|
왼쪽 비트 이동 | << | x<<y : x의 비트들을 y 칸만큼 왼쪽으로 이동 |
오른쪽 비트 이동 | >> | x>>y : x의 비트들을 y 칸만큼 오른쪽으로 이동 |
들어가기에 앞서)
왼쪽 비트 이동 연산자는 2배만큼 곱하는
효과,
오른쪽 비트 이동 연산자는 2배만큼 나누는
효과를 가지는 게 중요 포인트!
왼쪽으로 이동하며 없어지는 오른쪽 비트를 0
으로 채운다
★ 왼쪽으로 한 번 이동할 때마다 값이 2배
가 된다 => 곱셈 연산
∴
n개
의 왼쪽 비트 이동 시2^n
배 만큼 증가한다
오른쪽으로 이동하며 없어지는 왼쪽 비트를 부호비트
로 채운다
★ 오른쪽으로 한 번 이동할 때마다 값이 1/2배
가 된다 => 나눗셈 연산
오른쪽 비트 이동 연산자는 주의해야한다. MSB(최상위비트)의 여부에 따라 채워지는 값이 달라지기 때문이다.
양수
일 경우, unsigned/signed 상관없이 0
으로 채워지지만음수
일 경우, unsigned/signed 상관이 있다0
으로 채움 (어차피 양수니까)부호비트
의 값으로 채움 (0이면 0, 1이면 1)(그림은 생략한다. 위 그림에서 반대로 생각하면 된다.)
∴
n개
의 오른쪽 비트 이동 시1/(2^n)
배 만큼 증가한다
★ 가장 중요한 것 ★
<< 왼쪽 비트 이동 : n개
이동 시 2^n
배 증가
>> 오른쪽 비트 이동 : n개
이동 시 1/(2^n)
배 증가
주의 ! )
오른쪽 비트 이동은 MSB(최상위 비트) - 부호비트의 영향을 받는다.
쉽게 말해 양수일 경우 0
으로 채우지만, 음수일 경우 1
로 채워야한다.
곱셈이나 나눗셈 연산자는 속도가 느린 명령이다. 이에 반해 시프트 연산은 속도가 빠른 명령이라 2의 제곱으로 곱하거나 나눌 때 시프트 연산으로 대체 하면 속도가 더 빨라지는 장점을 가진다.
다만 몇 가지 주의하자면,
1) 시프트 연산자는 연산자 우선순위가 낮아서 다른 연산자와 사용할 경우 괄호를 꼭 이용하자.
2) 앞서 말했듯 부호가 있는 변수에 시프트 연산은 연산 특성이 달라진다. MSB가 1일 경우 나눗셈(>>)을 했을 때 언더플로하게 되면 부호 유지를 위해 빈자리가 1로 채워져 연산 특성이 달라진다. 따라서 음수를 다르는 경우에는 웬만하면 시프트 연산 사용보다는 그냥 나눗셈 연산을 수행하는 게 안전할 것이다.