Java에는 정수형(byte, short, int, long, char)의 비트를 조작하는 연산자가 있어요.
왼쪽으로 비트를 옮기려면 <<를, 오른쪽으로 옮기려면 >>를 사용해요.
// Shift two places to the left
0b0000_1011 << 2;
// # => 0b0010_1100
// Shift two places to the right
0b0000_1011 >> 2;
// # => 0b0000_0010
>>는 부호 있는 시프트 또는 산술 시프트 연산자라고도 하는데, 채워 넣는 비트가 부호 비트와 같기 때문이에요.
이 비트는 가장 왼쪽에 있는 비트로, 값이 양수면 0이고 음수면 1이에요.
<<로 왼쪽으로 시프트할 때는 항상 오른쪽에 0을 채워 넣어요.
// Shift 2 places to the right preserves the sign
// The binary value is two's complement of 0b0000_0110 (or 0x00000026), so the binary representation will be
// 1000_0000_0000_0000_0000_0000_0010_0110
int value = -0x7FFFFFDA;
// Shift two places to the right, preserving the sign bit
value >> 2;
// # => 1110_0000_0000_0000_0000_0000_0000_1001
오른쪽으로 시프트할 때 0을 채워 넣어야 한다면 대신 >>>를 사용해요.
시프트하면서 0을 채워 넣는 것을 논리 시프트라고도 해요.
// Shift two places to the right, inserting 0s on the left
value >>> 2;
// # => 0010_0000_0000_0000_0000_0000_0000_1001
비트 AND(&) 연산자는 두 값을 받아 각 비트에 대해 AND를 수행해요.
첫 번째 값의 각 비트를 두 번째 값의 같은 위치에 있는 비트와 비교해요.
둘 다 1이면 결과 비트는 1이 되고, 그렇지 않으면 0이 돼요.
0b0110_0101 & 0b0011_1100;
// # => 0b0010_0100
비트 OR(|) 연산자는 두 값을 받아 각 비트에 대해 OR을 수행해요.
첫 번째 값의 각 비트를 두 번째 값의 같은 위치에 있는 비트와 비교해요.
둘 중 하나라도 1이면 결과 비트는 1이 되고, 그렇지 않으면 0이 돼요.
0b0110_0101 | 0b0011_1100;
// # => 0b0111_1101
비트 XOR 연산자(^)는 두 값에 대해 비트 XOR을 수행해요.
비트 AND, 비트 OR 연산자와 마찬가지로 첫 번째 값의 각 비트를 두 번째 값의 같은 위치에 있는 비트와 비교해요.
둘 중 하나만 1이면 결과 비트는 1이 되고, 그렇지 않으면 0이 돼요.
0b0110_0101 ^ 0b0011_1100;
// # => 0b0101_1001
~)마지막으로 비트 NOT 연산자(~)는 각 비트를 뒤집어요.
앞의 연산자들과 달리 이 연산자는 값 하나에만 작용하는 단항 연산자예요.
~0b0110_0101;
// # => 0b1001_1010