python

0과 1, False와 True에서의 비트연산자

전라남도교육지원청 2024. 4. 9. 13:07

파이썬의 Boolean타입

파이썬에서는 True를 대체할 수 있는 다양한 수단이 존재한다. 예를 들어 이런 것들

numbers = map(int, input().split())
count = 0

while numbers:
    numbers.pop()
    count += 1

print(count)

numbers 배열의 길이가 0이 아니라면 while에 True로 전달된다.

 

또는 이런 것

k = 0
k = int(input())
if k:
    print("k has been changed")
else:
    print("k is still zero")

k의 값이 0이라면 if문에서 False로, 0이 아니라면 True로 전달된다. (정확히는 아님)

 

따라서 이런 표면적인 현상에 익숙해지면 이런 끔찍한 실수를 저지를 수 있는데 뭐냐면

바로 이런... 결과...

True, False가 하나의 비트가 아닌데 비트처럼 생각해버린다는 것이다.

 

원인

파이썬에서 boolean 데이터는 1바이트의 크기를 갖는다. 여기에 하나의 비트로 True냐 False냐를 결정한다.

 

따져보면 이렇다.

 

True = 0000 0001

False = 0000 0000

 

그래서 boolean 데이터에 비트시프트를 걸면 다음과 같은 결과를 얻는다.

>>> t = True
>>> print(t<<1)
2
>>> f = False
>>> print(f<<1)
0

그럼 이제 True에 비트연산자 '~'을 쓰면 어떻게 되는가, True의 반전은 False이기 때문에 1에서 0으로 바뀌어야 할 것 같지만 모든 비트가 반전되기 때문에 결과는 이렇다.

 

~True = 1111 1110

~False = 1111 1111

 

여기다 비트시프트를 걸면 이런 결과를 얻는다.

>>> t = True
>>> f = False
>>> print(~t)
-2	# 1111 1110
>>> print(~f)
-1	# 1111 1111
>>> print(~t<<2)
-8	# 1111 1000
>>> print(~f<<2)
-4	# 1111 1100

하지만 비트연산자가 아닌 논리연산자인 not을 쓰면 결과는 달라진다.

>>> t = True
>>> f = False
>>> print(not t)
False
>>> print((not t)<<2)
0	# 0000 0000
>>> print((not f)<<2)
4	# 0000 0100

 

결론

어떤 변수의 값을 통해 True/False를 판별하려는 경우, 반전을 줄 때, 특별한 경우가 아니라면 비트연산자는 사용하지 않는 것이 좋다.

True/False 값의 안전한 반전은 not 연산자로 할 수 있다.