오늘 이 글을 작성하는 이유는 ~
연산 때문이다. 그러나 ~
연산만 작성하기에는 애매해서 다른 비트 연산자도 정리하려고 한다.
파이썬에서 10진수를 2진수로 표현하려면 format()
이나 bin()
을 사용한다
In[1]: format(5, 'b')
Out[1]: '101'
In[2]: bin(5)
Out[2]: '0b101'
A. &
- AND 연산
- 둘 다 참일때만 만족
In[3]: bin(0b1010 & 0b1100)
Out[3]: '0b1000'
B. |
- OR 연산
- 둘 중 하나만 참이여도 만족
In[4]: bin(0b1010 | 0b1100)
Out[4]: '0b1110'
A. ^
- XOR 연산
- 둘 중 하나만 참일 때 만족
In[5]: bin(0b1010 ^ 0b1100)
Out[5]: '0b110' # 0b0110 --맨 앞의 0 생략--> 0b110
A. ~
- 보수 연산
- 0은 1로 1은 0으로 바꿈
In[6]: bin(0b1010)
Out[6]: '0b1010'
In[7]: bin(~0b1010)
Out[7]: '-0b1011'
In[8]: bin(-0b1010)
Out[8]: '-0b1010'
In[9]: bin(~-0b1010)
Out[9]: '0b1001'
In[10]: bin(-~0b1010)
Out[10]: '0b1011'
In[3]: bin(0b1010 & 0b1100)
Out[3]: '0b1000'
- OR 연산
- 둘 중 하나만 참이여도 만족
In[4]: bin(0b1010 | 0b1100)
Out[4]: '0b1110'
A. ^
- XOR 연산
- 둘 중 하나만 참일 때 만족
In[5]: bin(0b1010 ^ 0b1100)
Out[5]: '0b110' # 0b0110 --맨 앞의 0 생략--> 0b110
A. ~
- 보수 연산
- 0은 1로 1은 0으로 바꿈
In[6]: bin(0b1010)
Out[6]: '0b1010'
In[7]: bin(~0b1010)
Out[7]: '-0b1011'
In[8]: bin(-0b1010)
Out[8]: '-0b1010'
In[9]: bin(~-0b1010)
Out[9]: '0b1001'
In[10]: bin(-~0b1010)
Out[10]: '0b1011'
In[5]: bin(0b1010 ^ 0b1100)
Out[5]: '0b110' # 0b0110 --맨 앞의 0 생략--> 0b110
- 보수 연산
- 0은 1로 1은 0으로 바꿈
In[6]: bin(0b1010)
Out[6]: '0b1010'
In[7]: bin(~0b1010)
Out[7]: '-0b1011'
In[8]: bin(-0b1010)
Out[8]: '-0b1010'
In[9]: bin(~-0b1010)
Out[9]: '0b1001'
In[10]: bin(-~0b1010)
Out[10]: '0b1011'
~
연산은 무엇일까? ~
연산은 2진수 값의 0과 1을 바꾸는 것이다.
그런데 왜 In[7]
에서는 0b0101
이 아닌 -0b1011
이 반환되는 것일까?
그 이유는 다음 로직에서 알 수 있다.
- 1010(2) -> 10에 NOT(~) 연산을 사용해보자.
- 1010
- 0101 (1의 보수)
- 1010 (다시 1의 보수)
- 1011 (1을 더하여 2의 보수로 변환)
- -1011 (- 기호 추가, -11)
- 여기까지가
-0b1011
[1]
- 여기까지가
- 0101 (- 기호는 2의 보수로 변환할 수 있음)
- 기호를 적용한다면
~
연산 결과를 알 수 있음.
- 기호를 적용한다면
결국, ~
연산은 0과 1이 모두 반전되므로, 1의 보수를 찾는 것과 동일하다.
그래서 다음과 같은 결론도 도출이 가능하다. [2]
- 비트 연산자(NOT)는 2의 보수에서 1을 뺀 값
- 2의 보수(수학 연산)은 비트 연산자(NOT)에서 1을 더한 값
In[8]
은 단순히 0b1010
에 -
부호를 붙인 것이다.
In[9]
는 -0b1010
의 -
부호를 2의 보수로 변환(0b0110
)하고 ~
부호를 적용하여 -0b0111
에서 -
부호를 2의 보수로 변환하여 0b1001
을 만들어낸다.
그런데 여기서 ~
연산자를 적용할 때 왜 -0b0111
이 아닌 0b1001
인지는 잘 모르겠다.
In[10]
은 In[7]
에서 -
부호만 제거한 것이다.
A. <<
- 왼쪽 시프트 연산자
- 변수의 값을 왼쪽으로 지정된 비트 수 만큼 이동
In[11]: bin(0b101011 << 2)
Out[11]: '0b10101100'
A. <<
- 오른쪽 시프트 연산자
- 변수의 값을 오른쪽으로 지정된 비트 수 만큼 이동
In[12]: bin(0b101011 >> 2)
Out[12]: '0b1010'
참고자료
In[11]: bin(0b101011 << 2)
Out[11]: '0b10101100'
- 오른쪽 시프트 연산자
- 변수의 값을 오른쪽으로 지정된 비트 수 만큼 이동
In[12]: bin(0b101011 >> 2)
Out[12]: '0b1010'
참고자료
[1] 빌노트. 파이썬 비트연산자 사용법 정리 (Python 비트연산) (withcoding.com). Tistory. (accessed Nov 8. 2021)
[2] joon96. [Python] 비트 연산 (tistory.com). Tistory. (accessed Nov 8. 2021)
Ghost