비트 연산자는 일반 코드를 작성할 때 사용한 적이 없지만 코딩테스트에서는 심심치 않게 출제되므로 정리할 필요를 느낀다.
비트 연산자는 정수타입의 데이터를 2진수로 계산하는 연산자이다. (피연산자로 실수는 허용하지 않는다.)
2진수는 말 그대로 1이나 0으로 표현되는 것을 의미하며, 여기서 bit는 1이나 0을 나타낸다.
2진법(2진수)
컴퓨터에서 데이터를 표현하기 위해 사용된다. 2를 기반으로 1과 0으로 표현된다.
10진수 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
2진수 | 0 | 1 | 10 | 11 | 100 | 101 | 110 | 111 | 1000 | 1001 | 1010 |
2의 보수
2의 제곱수에서 빼서 얻은 이진수를 의미하며, 컴퓨터가 음수를 저장하기 위해 사용되는 방식 중 하나이다.
기본적으로 비트는 2의 제곱수로 표현이 된다. 예를 들어 4비트의 2진수를 2^4(=16) 개의 값을 표현할 수 있다. 모든 값을 양수로 표현한다면 0부터 15까지의 정수표현이 가능하겠으나, 우린 음수의 대한 표현식도 필요하다.
그렇기 때문에 수의 절반은 음수로 할당시키게 된다. 음수를 나타내는 기준은 `왼쪽의 첫 번째 비트`이며, 0이면 양수, 1이면 음수를 나타낸다.
# | 2진수 | 부호있는 10진수 |
1 | 0000 | 0 |
2 | 0001 | 1 |
3 | 0010 | 2 |
4 | 0011 | 3 |
5 | 0100 | 4 |
6 | 0101 | 5 |
7 | 0110 | 6 |
8 | 0111 | 7 |
9 | 1000 | -8 |
10 | 1001 | -7 |
11 | 1010 | -6 |
12 | 1011 | -5 |
13 | 1100 | -4 |
14 | 1101 | -3 |
15 | 1110 | -2 |
16 | 1111 | -1 |
어떤 수의 보수의 의미는 기본적으로 더했을때 자리올림이 발생하는 수를 의미한다. 10진수에서 3의 보수는 7이 된다. 3+7 = 10 이므로 자리올림수가 발생되기 때문이다. 이진수에서도 마찬가지이다. 2진수 3의 2의 보수를 구한다면, 11(2)의 자리올림인 100이 되기 위한 수가 2의 보수가 된다. 11(2) + 01(2) = 100(2)
음수를 2진수로 표현하기
2의 보수는 2진수에서는 음수를 표현한다. 음수란 10진수에서 3의 음수는 -3이고 이 값을 더하면 0이 된다.
예를 들어 5의 음수값을 구한다고 한다면 (5 + -5 = 0)이라는 것을 생각하면 된다.
양수 5의 2진수는 0101이고, 이것을 더했을 때 1 0000이 되기 위해선 1011이 필요한 것을 알 수 있다.
1 0000에서 0101을 빼서 구하거나 할 수도 있지만 가장 쉬운 방식은 음수의 절댓값의 반전 수를 활용하는 것이다.
-5의 절대값 5의 값의 2진수 값 = 0101에서 비트를 반전시킨다.
1010이 되며, 여기서 +1 해준 값이 2의 보수값이 된다.
= 1011
반대로 2의 보수를 10진수를 변환할려면 반대의 과정으로 진행하면 된다.
1011 - 1 = 1010를 다시 반전 시켜 0101로 표현하여 5의 값을 구한 후 음수 부호를 붙여주면 된다.
비트 연산자
&(AND 연산자)
- 두 개의 비트값이 모두 1인 경우에만 결과 1을 얻는다. 그 외에는 0을 얻는다.
- ex) 5 & 3 -> 1
|(OR 연산자)
- 두 개의 비트 값 중 하나라도 1이면 결과값 1을 얻고, 그 외는 0을 얻는다.
- ex) 5 | 3 -> 7
^(XOR 연산자)
- 두 개의 비트 값이 같으면 0, 다르면 1를 나타낸다.
- ex) 5 ^ 3 -> 6
~(반전 연산자)
- 비트 값이 0이면 1, 1이면 0으로 반전시킨다.
비트 이동 연산자 (<<, >>, >>>)
<< 연산자
- 비트를 왼쪽으로 이동
- ex) 3 << 1 (3의 비트값을 1만큼 좌측으로 이동시킨다.)
이때 자리 이동으로 생긴 빈 값 (위에선 bit4)은 0으로 채워진다. 반대로 저장범위 이탈 수는 버려지게 된다.
>> 연산자
- 비트를 오른쪽으로 이동
- ex) 3 >> 1 (3의 비트를 1만큼 오른쪽으로 이동한다.)
>>> 연산자
- << 연산자의 경우 피연산자의 부호와 상관없이 각 자리를 이동시키면서 빈칸을 0으로 채우면 되지만 >> 연산자의 경우 기존 값이 음수인 경우는 1, 양수인 경우 0으로 기존 부호를 따라가게 된다.
- >>> 연산자의 경우 부호비트와 상관없이 0으로 채우게 된다.
'Language > Java' 카테고리의 다른 글
[Java] startsWith와 endsWith (0) | 2024.11.15 |
---|---|
[java] Arrays.asList() remove(), add() java.lang.UnsupportedOperationException 발생 (0) | 2024.07.31 |
[JAVA] 람다식과 함수형 인터페이스 (0) | 2024.05.02 |
[인프런 워밍업 스터디 클럽 1기] 어노테이션의 역할 (0) | 2024.04.30 |
[스진초5기/Java] Overriding과 Overloading (0) | 2023.10.27 |