비트연산자는 정수값을 비트 단위로 연산할 수 있다.
1은 true, 0은 false라고 간주하고 계산한다. 출력 결과도 정수이다.
비트 연산자의 종류로는(&, |, ^, ~, >>, << 등)이 있다.
정수값을 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진수화 했을 때 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
정수값을 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
정수값을 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 비트 이동할 때 마다 곱하기 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로 나눈 나머지 값을 비트 이동으로 간주한다.
오른쪽으로 비트를 이동한다. 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