자바 - 비트이동연산자
업데이트:
비트이동연산자?
비트연산자는 정수값을 비트 단위로 연산할 수 있다.
1은 true, 0은 false라고 간주하고 계산한다. 출력 결과도 정수이다.
비트 연산자의 종류로는(&, |, ^, ~, », « 등)이 있다.
1. &연산자
정수값을 2진수화 했을 때 and연산으로 모두 true일때만 true값인 1을 리턴한다.
System.out.println(a & b);
// a = 0000 0000 0000 0000 0000 0000 0110 1100
// b = 0000 0000 0000 0000 0000 0000 0101 0101
// --------------------------------------------
// 0000 0000 0000 0000 0000 0000 0100 0100 = 68
2. |연산자
정수값을 2진수화 했을 때 or연산으로 true가 하나라도 있다면 true값인 1을 리턴한다.
System.out.println(a | b);
// a = 0000 0000 0000 0000 0000 0000 0110 1100
// b = 0000 0000 0000 0000 0000 0000 0101 0101
// --------------------------------------------
// 0000 0000 0000 0000 0000 0000 0111 1101 = 125
3. ^ 연산자
정수값을 2진수화 했을 때 true(1), false(0)값이 일치하지 않을 때만 true값인 1을 리턴한다.
System.out.println(a ^ b);
// a = 0000 0000 0000 0000 0000 0000 0110 1100
// b = 0000 0000 0000 0000 0000 0000 0101 0101
// --------------------------------------------
// 0000 0000 0000 0000 0000 0000 0011 1001 = 57
4. ~ 연산자
정수값을 2진수화 했을때 true와 false 를 모두 바꿔 리턴한다. 비트연산에서의 not은 !가 아니라 ~연산자이다.
System.out.println(~a);
// a = 0000 0000 0000 0000 0000 0000 0110 1100 = 108
// --------------------------------------------
// 1111 1111 1111 1111 1111 1111 1001 0011 = -109
위의 비트연산자는 어디에 쓰이는가?
이미지 및 영상처리에 사용된다.
예) 마스킹, 오버레이 기법에 사용된다.
예) 색조 변경에 사용된다.
- 비트 연산 활용의 예
흑백을 반전시키는 방법:
빛이 있는 점은 빛을 없애고 (1 –> 0)
빛이 없는 점은 빛을 넣는다.(0 –> 1)
=> 다음과 같이 흑색의 한 점이 있다.
00000000 00000000 00000000 (변경전 색: 검정)
~
11111111 11111111 11111111 (변경한 색: 흰색)
5. « 연산자
왼쪽으로 비트를 이동한다.
1 비트 이동할 때 마다 곱하기 2 한것과 같은 효과를 준다.
오른쪽 빈자리는 0으로 채운다.
값을 2의 제곱수로 증가시킬 땐 곱하기 연산을 하는 것 보다 왼쪽 비트 이동 연산을 하는 것이 빠르기 때문에 실무에서도 자주 쓰인다.
int i = 1;
// [00000000000000000000000000000001] = 1
System.out.println(i << 1);
// 0[0000000000000000000000000000001 ]
// [00000000000000000000000000000010] = 2
System.out.println(i << 2);
// 00[000000000000000000000000000001 ]
// [00000000000000000000000000000100] = 4
System.out.println(i << 3);
// 000[00000000000000000000000000001 ]
// [00000000000000000000000000001000] = 8
System.out.println(i << 4);
// 0000[0000000000000000000000000001 ]
// [00000000000000000000000000010000] = 16
음수에 « 연산을 쓰게되면 부호비트에 상관없이 무조건 이동한다. 음수에 쓰게되면 양수로 바뀌어버린다!
int a = -0x7f_ff_ff_fa;
// -21_4748_3642
System.out.println(a)
[10000000000000000000000000000110]
System.out.println(a << 1);
1[00000000000000000000000000001100] = 12
비트이동 연산은 int타입 값에선 0~31까지 유효하다. 만약 31을 넘는 경우 나눈 나머지 값을 비트 이동으로 간주한다.
long타입의 경우 비트 이동은 0~63까지 유효하다. 만약 63을 넘는 경우 64로 나눈 나머지 값을 비트 이동으로 간주한다.
6. », »> 연산자
오른쪽으로 비트를 이동한다. 1비트 이동할 때 마다 나누기 2 한 것 같은 효과를 준다.
/ 나누기 연산을 수행하는 것 보다 계산 속도가 빨라서 실무에서는 나눗셈 연산이 시간과 CPU사용량이 많이 들기 때문에 소수점 이하까지 정확하게 계산할 것이 아니라면 » 비트 이동 연산자를 주로 사용한다.
(»)연산자는 왼쪽 빈자리를 원래 숫자와 같은 부호값으로 채운다.
양수라면 0, 음수라면 1을 채운다.
- 양수의 경우!
int i = 105;
// [00000000000000000000000001101001]
System.out.println(i >> 1);
// [ 0000000000000000000000000110100]1
// [00000000000000000000000000110100] => 52
- 음수의 경우!
int i = -87;
// [11111111111111111111111110101001]
System.out.println(i >> 1);
// [ 1111111111111111111111111010100]1
// [11111111111111111111111111010100]1 => -44
- 참고! (»>)연산자는 오른쪽으로 비트를 이동하는 것은 같지만, 왼쪽 빈자리를 음수 양수 상관없이 무조건 0으로 채운다.
댓글남기기