파이썬의 비트 연산자 분석

오늘 이 글을 작성하는 이유는 ~ 연산 때문이다. 그러나 ~ 연산만 작성하기에는 애매해서 다른 비트 연산자도 정리하려고 한다.

파이썬에서 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'

~ 연산은 무엇일까? ~ 연산은 2진수 값의 0과 1을 바꾸는 것이다.

그런데 왜 In[7]에서는 0b0101이 아닌 -0b1011이 반환되는 것일까?

그 이유는 다음 로직에서 알 수 있다.

  1. 1010(2) -> 10에 NOT(~) 연산을 사용해보자.
  2. 1010
  3. 0101 (1의 보수)
  4. 1010 (다시 1의 보수)
  5. 1011 (1을 더하여 2의 보수로 변환)
  6. -1011 (- 기호 추가, -11)
    • 여기까지가 -0b1011 [1]
  7. 0101 (- 기호는 2의 보수로 변환할 수 있음)
      • 기호를 적용한다면 ~ 연산 결과를 알 수 있음.

결국, ~ 연산은 0과 1이 모두 반전되므로, 1의 보수를 찾는 것과 동일하다.

그래서 다음과 같은 결론도 도출이 가능하다. [2]

  1. 비트 연산자(NOT)는 2의 보수에서 1을 뺀 값
  2. 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'

참고자료

[1] 빌노트. 파이썬 비트연산자 사용법 정리 (Python 비트연산) (withcoding.com). Tistory. (accessed Nov 8. 2021)

[2] joon96. [Python] 비트 연산 (tistory.com). Tistory. (accessed Nov 8. 2021)

이 글이 도움이 되었나요?

신고하기
0분 전
작성된 댓글이 없습니다. 첫 댓글을 달아보세요!
    댓글을 작성하려면 로그인이 필요합니다.