오늘은 자주 사용되진 않지만, 나중에 필요할 때 참고하기 위해서
비트연산
에 대해 짧게 정리해보려고 한다.
파이썬의 비트연산은 c, java와 다를게 없다.
종류 | 의미 |
---|---|
>> | 오른쪽 shift |
<< | 왼쪽 shift |
& | 비트 AND |
^ | 비트 XOR |
| | 비트 OR |
5가지 종류가 있고, 모두 2진수
로 생각해서 계산한다.
shift 연산은 왼쪽 shift와 오른쪽 shift가 있다.
10진수 5를 가지고 비트연산을 해보자.
a = 5
print(bin(a)) # 2진수값 구하기
print(a << 2) #오른쪽 shift
print(a >> 2) #왼쪽 shift
5의 2진수 값 = 0b101
5를 오른쪽으로 두 칸 shift한 값 = 1이 출력된다.
5를 왼쪽으로 두 칸 shift한 값 = 20이 출력된다.
왜 이런 결과가 나오는걸까?
5는 2진수로 0b101이다.
이동 | 값 변화 |
---|---|
오른쪽으로 2칸 이동 | ob1 = 1 |
왼쪽으로 2칸 이동 | 0b10100 = 20 |
왼쪽으로 밀때는 0을 뒤로 붙이면 된다.
오른쪽으로 미는 경우는 오른쪽 끝에 있는 비트는 없어진다.
이 연산은 비트끼리 AND 연산이다.
같은 자리 수 끼리 &연산을 하며 두 수 모두 1인 경우에만 1이된다.
연산 전 | 연산 후 |
---|---|
1 & 1 | 1 |
1011 & 1111 | 1011 |
101101 & 101010 | 101000 |
다음 예시 참고!
이는 XOR연산으로 연산하는 두 비트 값이 다르면 1이된다.
연산 전 | 연산 후 |
---|---|
1 ^ 0 | 1 |
1 ^ 1 | 0 |
1011 ^ 1111 | 0100 |
|는 OR연산이다.
shift + \
를 하면 '|'를 사용할 수 있다.
연산하는 두 비트 중 하나만 1이어도 1이된다.
연산 전 | 연산 후 |
---|---|
1 | 1 | 1 |
1 | 0 | 1 |
0 | 0 | 0 |
0 | 1 | 1 |
111 | 011 | 111 |
이번 연산은 자주 사용하지 않는 개념이기 때문에 쪼금 어렵다.
~연산을 알기 전에 보수 개념을 알아야 한다.
보수
는 '보충을 해주는 수' 라는 의미로 컴퓨터가 뺄셈을 할 때 사용되는 개념이다.
컴퓨터는 뺄셈을 할 수 없어서 x-y라는 뺄셈을
x+(-y)라는 덧셈으로 바꿔 처리해야 한다.
이때, +(-y)가 보수
가 된다.
보수 표현은 1의 보수와 2의 보수로 나눌 수 있다.
1의 보수 표현이란 2진수에서 '1을 뺀 커다란 2의 제곱수'에서 '어떤 수'를 빼서 얻은 값이다.
예를 들어 10진수 6을 2진수로 변환하면 110이다.
110을 어떤 수
로 가정했을 때 한 자릿수가 더 많은 1000이 커다란 2의 제곱수
가 된다.
여기서 1을 뺀 111이 바로 1을 뺀 커다란 2의 제곱수
가 된다.
111에서 110을 뺀 값인 001이 110의 1의 보수 표현
이 된다.
2의 보수 표현은 2진수에서 '커다란 2의 제곱수'에서 '어떤 수'를 빼서 얻은 값이다.
2진수 110을 어떤 수
로 예로 들면,
커다란 2의 제곱수
는 1000이 된다.
1000에서 110을 뺀 값인 010이 바로 110의 2의 보수 표현
이 된다.
이제 ~연산으로 돌아오면
>>> bin(~0b1100)
'-0b1101'
>>> ~ 12
-13
>>> ~ 3
-4
>>> ~ 0
-1
0b1100는 10진수 12다.
~연산자를 취했더니 -13이라는 결과가 나온다.
~3의 결과도 -4가 나왔다.
즉, x라는 값을 넣으면 다음과 같은 값이 나온다는 것이다.
~x = -x -1
즉 2의 보수를 취하고 그 값에서 1을 빼주는 연산을 해주면 된다.
낯선 개념이 등장해서 어렵지만, 다시 한 번 천천히 봐보자.