[Java] 비트 연산자 / 시프트 연산자

by Blogger 하얀쿠아
2012. 2. 2. 10:45 소프트웨어 Note/Java

[Java] 비트 연산자 / 시프트 연산자


자바언어에는 C/C++ 와 동일하게 비트연산자들인 '&', '|', '^', '~' 와 시프트연산자인 '<<' 와 '>>' 가 있습니다.

그러나 자바에만 있는 연산자가 있는데요.

바로  '>>>' 라는 연산자가 추가적으로 존재합니다.

순서대로 정리해 보도록 하겠습니다.


비트연산자

컴퓨터 내부의 데이터를 비트 단위로 비교하거나 조작할 때 사용한다.


1. 논리곱 (and) &

각 비트를 비교하여 양쪽 모두 1이면 1, 아니면 0을 반환함.


ex) a = 110, b= 220

a = 0 1 1 0 1 1 1 0

b = 1 1 0 1 1 1 0 0 

a&b =  0 1 0 0 1 1 0 0


2. 논리합 (or) |

각 비트를 비교하여 어느 한쪽이 1 이면 1, 그렇지 않으면 0을 반환함.


ex) a = 110, b= 220

a = 0 1 1 0 1 1 1 0

b = 1 1 0 1 1 1 0 0 

a|b =  1 1 1 1 1 1 1 0


3. 배타적 논리합(xor) ^

각 비트를 비교하여 한쪽이 1이고 다른 한쪽이 0이면 1을, 아니면 0을 반환함.


ex) a = 110, b= 220

a = 0 1 1 0 1 1 1 0

b = 1 1 0 1 1 1 0 0 

a^b =  1 0 1 1 0 0 1 0 


4. 1의 보수 표현(not) ~

각 비트를 반전시킨 값을 반환함.


ex) a = 110

a = 0 1 1 0 1 1 1 0

~a =  1 0 0 1 0 0 0 1



시프트 연산자

비트 열을 좌우로 지시한 만큼 이동시키는(shift) 연산자를 말합니다.
본문 처음에 말했듯이, C/C++ 에는 >> 와 << 만  존재하지만, 자바에는 추가적으로 '>>>' 연산자가 있습니다.

1. 왼쪽 시프트 연산자 <<

ex) 150 << 2
150 의 이진값을 왼쪽으로 2칸 시프트 합니다.
 
     1 0 0 1 0 1 1 0 : 150
1 0 0 1 0 1 1 0 0 0 : 600

위와 같은 결과. 왼쪽으로  두칸 밀면서, 비게 되는 오른쪽 두칸은 0으로 채웁니다.
만약 데이터를 담는 자료형이 byte 타입이었다면, (8bit) 왼쪽으로 밀린 2개의 비트는 삭제됩니다.

그런 경우 다음과 같은 결과가 됩니다
    0 1 0 1 1 0 0 0 :  88
 

2. 오른쪽 시프트 연산자 >> 

ex) 150 >> 2
150의 이진값을 오른쪽으로 2칸 시프트 합니다.

    1 0 0 1 0 1 1 0
    1 1 1 0 0 1 0 1 1 0

오른쪽으로 2비트 이동 한 후, 비게되는 왼쪽의 2개비트는 1로 채워지고, 오른쪽에서 2비트 넘어간 부분은 삭제됩니다. 
따라서 결과는 아래가 됩니다.
    1 1 1 0 0 1 0 1 

주의점 : 무조건 왼쪽에 비는 부분이 1로 채워지는 것이 아닙니다. -> 밀기전 최초 첫째짜리 값(MSB)과 동일한 값으로 채워집니다.


3. 논리 오른쪽 시프트 연산자 >>>

150 >>> 2
오른쪽으로 2비트 시프트 합니다.

자바에 추가된 논리 시프트는 오른족으로 밀면서 비게되는 앞쪽 비트를 무조건 0으로 채워넣는 것이다.

    1 0 0 1 0 1 1 0
    0 0 1 0 0 1 0 1 1 0

으로 되는 것. 비게 되는 왼쪽 2비트가 무조건 0 으로 채워집니다.
밀려난 오른쪽 2개비트 1 0 은 삭제됩니다.


G.711 코덱 구현을 하면서 비트연산자와 시프트 연산자를 사용할 일이 꽤 많았어요.
그런데 몇 몇 연산자의 용법을 자주 혼동하게 되어서, 다시 한번 정리를 해봅니다.


즐거운 코딩 하세요!



이 댓글을 비밀 댓글로
    • 알롱싸
    • 2012.08.07 17:28
    왼쪽 시프트 연산자 결과값 (1 1 1 0 0 1 0 1) 은 어떻게 나오는거에요?
    • 왼쪽 시프트 연산자가 아니라 오른쪽 시프트 연산자 에서의 예제를 말씀하신 것 같이 보이는 군요.

      10010110 에서 오른쪽으로 2칸을 밀게 되면 MSB(제일 왼쪽에 있는 숫자)인 1과 같은 숫자로 2개가 채워지고 밀린 숫자는 없어집니다.
      ->> 이렇게 2칸 밀면
      즉, [11]100101(10) 이렇게 되겠죠
      [ ] 안이 채워진 숫자이고, ( ) 안이 없어진 숫자 입니다.