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
// This is a negative value, whose binary representation is
// 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을 채워 넣어야 한다면, 대신 >>> 연산자를 사용해요.
// 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
친구가 방금 중요한 비밀이 담긴 메시지를 보냈어요. 다른 사람들이 쉽게 읽지 못하게 하려고, 메시지는 일련의 비트 조작을 거쳐 암호화되었어요. 메시지를 복호화할 수 있도록 메서드들을 작성해야 해요.
메시지를 복호화하는 첫 단계는 암호화 과정에서 시프트한 비트를 오른쪽으로 다시 시프트해서 되돌리는 거예요. 복호화 과정의 이후 단계들은 왼쪽에서 0이 채워진다고 가정해요.
값과 시프트할 자릿수를 받아 시프트를 수행하는 Secrets.shiftBack 메서드를 구현해요.
Secrets.shiftBack(0b1001, 2);
# => 0b0010
다음으로, 1로 설정해야 하는 비트들이 있어요.
값과 마스크를 받아 값의 비트를 1로 설정한 결과를 반환하는 Secrets.setBits 메서드를 구현해요.
마스크의 비트가 1인 자리에서는 값의 비트도 1로 설정되어야 해요.
나머지 비트는 모두 그대로 유지되어야 해요.
Secrets.setBits(0b0110, 0b0101);
# => 0b0111
암호화 과정에서 일부 비트가 뒤집혀요. 메시지를 복호화하려면 이 비트들을 다시 뒤집어야 해요.
값과 마스크를 받는 Secrets.flipBits 메서드를 구현해요.
마스크는 값에서 어떤 비트를 뒤집을지 알려줘요.
마스크의 비트가 1이면, 값의 해당 비트가 뒤집혀요.
나머지 비트는 모두 그대로 유지돼요.
Secrets.flipBits(0b1100, 0b0101);
# => 0b1001
마지막으로, 항상 0으로 복호화되는 특정 비트들도 있어요.
값과 마스크를 받는 Secrets.clearBits 메서드를 구현해요.
마스크의 비트가 1인 자리에서는 value의 비트가 0으로 설정되어야 해요.
나머지 비트는 모두 그대로 유지되어야 해요.
Secrets.clearBits(0b0110, 0b0101);
# => 0b0010
Exercism에 가입하고 Java 트랙을 개념 26개연습 문제 158개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.