본문 바로가기

Java/Learn_Java

Java의 비트 연산자 이용법

세상에 쓰지 않는 기술은 없다.

연산자의 최종 보스 냄새가 나는 "비트 연산자!!!!!"라는 다소 무시무시해 보이는 이름은 우리와 강사님을 떨게 만들었고, 실전에서 잘 안 쓴다는 이유로 그냥 생략했다.

다만 두 번째엔 굉장한 탐구적인 태도를 가진 강사님이 설명해줬는데, 조금 정리가 필요할 것 같다.

 

Java의 연산자 중에는 01010111 과 같이 2진수 문자의 특정한 부분을 변경할 수 있는 비트와 관련된 연산자들이 몇 개 있는데,

수업에서 들었던 활용법을 복습 겸 써보려고 한다.

 

우리가 색상을 숫자로 표현할 때 다음과 같은 치수를 종종 본 적이 있었을 것이다.

(물론 우리가 쓰는 색상은 32비트이기 때문에 이것과는 좀 다르다.)

Color=0xFFFF, 0x91F5, 0xCD59...

여기서 0x는 16진수라는 것을 컴퓨터에게 알려주는 용어이고, 뒤에 있는 네 글자가 색상을 가리키는 16진수의 숫자였다.

그중 0xCD59가 어떤 것인지 해석하기 위해, 이를 2진수로 풀어 쓸 경우 다음과 같다.

int color = 0xCD59;
1100 1110 0101 1001
  "R"      "G"     "B"
(1100 1)(110 010)(1 1001)

각각의 가로로 친 부분이 왼쪽부터 R, G, B에 해당한 부분이라고 가정하자.

우리의 목표는 위와 같이 짬뽕되어 있는 RGB중 한 부분의 색상만 추출해 그 숫자를 알고 싶다.

다른 말로 R의 색깔이 어떻게 되는지만 알고 싶다.

그렇다면 어떻게 해야 할까?

가장 오른쪽에 있는 R을 보자.

   "R"     "G"     "B"
(1100 1)(110 010)(1 1001)

비트 이동 연산자 >>는 오른쪽 방향으로 입력한 숫자만큼 비트를 이동시켜준다.

가장 오른쪽자리에서 밀린 비트들은 삭제된다.

여기서 비트를 11 이동시키면 다음과 같아진다.

int color = 0xCD59;
1100 1110 0101 1001
color = color >> 11;//아래가 연산결과임
0000 0000 0001 1101

이걸 10진수로 바꿔주면 R의 숫자를 얻을 수 있다.(29)

 

G는 조금 더 복잡하다. 아까와 똑같은 방법을 한 뒤에 뒤에 있는 부호를 & 연산을 통해 0으로 만들어야 한다.

우선 아까처럼 >>5 를 통해 B를 없앤 후,

G의 자릿수만큼 비트 1을 논리곱한다.(11 1111)

2진수 11 1111은 16진수로 0x3F니 다음과 같이 하면 될 것이다.

int color = 0xCD59;
1100 1110 0101 1001
  "R"      "G"     "B"
(1100 1)(110 010)(1 1001)
color = color >> 5;
0000 0(110 01)(11 0010)
color = color & 0x3F;

0000 0(110 01)(11 0010)
0000 0(000 00)(11 1111)

비트 논리곱 연산자는 양쪽이 모두 1이 있어야 1로 출력되기 때문에, 위 아래 중 어느 한 쪽이라도 0이 있으면 0으로 계산한다. 계산하면,

0000 0(000 00)(11 0010)

이렇게 된다.

이걸 10진수로 바꾸면

내가 원하는 숫자인 50이 나온다!

 

마지막으로 B 부분은 논리곱만 하면 쉽게 추출할 수 있다.

int color = 0xCD59;
1100 1110 0101 1001

int color = color & 0x1F;
  "R"      "G"     "B"
(1100 1)(110 010)(1 1001)
(0000 0)(000 000)(1 1111)
->
(0000 0)(000 000)(1 1001)

이런 식으로 결과가 나올 것이고, 10001은 10진수로 25이니 B 값은 25가 나온다.

 

어려워 보이지만 생각보단 별 것 없다.

이 부분을 실전 32비트 숫자에(16진수 6자리) 적용해 계산하면, 각각의 RGB 값을 구할 수 있을 것이다.

(물론 굳이 이렇게 안 해도 쉽게 구하게 정리해놓은 사이트가 있겠지...)