ch19 Bit Manipulation

비트 조작 개요

부울 연산자

NOT

X NOT X
false true
true false
print("not True: {}".format(not True))  # -2: True는 1로 간주, -1 -1 = -2
print("not False: {}".format(not False))  # -1: False는 0으로 간주, 0 - 1 = -1

AND

X Y X AND Y
false false false
false true false
true false false
true true true
print("True and True: {}".format(True and True))
print("True and False: {}".format(True and False))
print("False and True: {}".format(False and True))
print("False and False: {}".format(False and False))

OR

X Y X OR Y
false false false
false true true
true false true
true true true
print("True or True: {}".format(True or True))
print("True or False: {}".format(True or False))
print("False or True: {}".format(False or True))
print("False or False: {}".format(False or False))

XOR

X Y X OR Y
false false false
false true true
true false true
true true false
# and와 or를 조합하여 xor 구현
# (X and not Y) or (Y and not X)
# 1. X 또는 Y 두 변수 중 하나를 NOT 연산 후 AND 연산
# 2. 둘 중 하나라도 결과 True면 XOR에서 True
print("(True and not True) or (not True and True): {}".format((True and not True) or (not True and True)))
print("(True and not False) or (not True and False): {}".format((True and not False) or (not True and False)))
print("(False and not True) or (not False and True): {}".format((False and not True) or (not False and True)))
print("(False and not False) or (not False and False): {}".format((False and not False) or (not False and False)))

비트 연산자(Bit Operator)

비트 연산자 ~

print("~ True: {}".format(~ True)) # -2
print("~ False: {}".format(~ False)) # -1

비트 연산자 &

print("True & True: {}".format(True & True))
print("True & False: {}".format(True & False))
print("False & True: {}".format(False & True))
print("False & False: {}".format(False & False))

비트 연산자 |

print("True | True: {}".format(True | True))
print("True | False: {}".format(True | False))
print("False | True: {}".format(False | True))
print("False | False: {}".format(False | False))

비트 연산자 ^

print("True ^ True: {}".format(True ^ True))
print("True ^ False: {}".format(True ^ False))
print("False ^ True: {}".format(False ^ True))
print("False ^ False: {}".format(False ^ False))

print("True is not True: {}".format(True is not True))
print("True is not False: {}".format(True is not False))
print("False is not True: {}".format(False is not True))
print("False is not False: {}".format(False is not False))

비트 조작 퀴즈

비트 조작 +

print("bin(0b0110 + 0b0010) = bin({} + {}) = {} = {}".format(0b0110, 0b0010, bin(0b0110 + 0b0010), 0b0110 + 0b0010))
# bin(0b0110 + 0b0010) = bin(6 + 2) = 0b1000 = 8

비트 조작 *

print("bin(0b0011 * 0b0101) = bin({} * {}) = {} = {}".format(0b0011, 0b0101, bin(0b0011 * 0b0101), 0b0011 * 0b0101))
# bin(0b0011 * 0b0101) = bin(3 * 5) = 0b1111 = 15

비트 조작 >>

# 비트 두 개 우측으로 옮기므로 2^2로 나눈 것과 같다
print("bin(0b1101 >> 2) = bin({} >> 2) = {} = {}".format(0b1101, bin(0b1101 >> 2), 0b1101 >> 2))
# bin(0b1101 >> 2) = bin(13 >> 2) = 0b11 = 3

비트 조작 <<

print("bin(0b1101 << 2) = bin({} << 2) = {} = {}".format(0b1101, bin(0b1101 << 2), 0b1101 << 2))
# bin(0b1101 << 2) = bin(13 << 2) = 0b110100 = 52

비트 조작 ~

print("bin(~0b1100) = {} = {}".format(bin(~0b1100), ~0b1100))
# bin(~0b1100) = -0b1101 = -13

비트 조작 ^

EXPECTED ACTUAL
0b0101 0b0101
~0b1100 ~0b1100
0b0011 1111 0011
0b0110 1111 0110
6 -10
print("bin(0b0101 ^ ~0b1100) = bin({} ^ {}) = bin({} ^ {}) = {} = {}".format(bin(0b0101), bin(~0b1100), 0b0101, ~0b1100, bin(0b0101 ^ ~0b1100), 0b0101 ^ ~0b1100))
# bin(0b0101 ^ ~0b1100) = bin(0b101 ^ -0b1101) = bin(5 ^ -13) = -0b1010 = -10

보수

1의 보수

1_complement_1

1_complement_2

84 - 67
  0101 0100
- 0100 0011

  0101 0100
+ 1011 1100 # 1의 보수
 10001 0000 # 순환 자리 올림수(end-around carry) 1이 생기면 다시 더한다

  0001 0000
+         1
  0001 0001 = 17

2의 보수

  2의 보수 NOT
비트 연산 비트 반전 후 +1 2의 보수 - 1
10진수 표현   -x - 1

2의 보수 as 숫자 포맷

십진수 비트 비트 반전 후 +1    
0 0000 1111 + 1 0000 0
1 0001 1110 + 1 1111 -1
2 0010 1101 + 1 1110 -2
3 0011 1100 + 1 1101 -3
4 0100 1011 + 1 1100 -4
5 0101 1010 + 1 1011 -5
6 0110 1001 + 1 1010 -6
7 0111 1000 + 1 1001 -7
8 1000 0111 + 1 1000 -8
MASK = 0xF # 15 = 1111
print("bin(1 & MASK) = {}".format(bin(1 & MASK)))
print("bin(7 & MASK) = {}".format(bin(7 & MASK)))
print("bin(-8 & MASK) = {}".format(bin(-8 & MASK)))
print("bin(-7 & MASK) = {}".format(bin(-7 & MASK)))
print("bin(-1 & MASK) = {}".format(bin(-1 & MASK)))
"""
bin(1 & MASK) = 0b1
bin(7 & MASK) = 0b111
bin(-8 & MASK) = 0b1000
bin(-7 & MASK) = 0b1001
bin(-1 & MASK) = 0b1111
"""

2의 보수 as 수학 연산

예제1: 0111 = 7
0111의 2의 보수 연산
   
  0111 = 7
비트 반전 1000
+1 1001
  -7
1001의 NOT연산
   
  1001 = -7
NOT ~1000
  0111
-1 0110
  6

NOT 1000 = ~1000 = -x(비트 반전) -1 = 0111 -1 = 0110 = 6

예제2

비트 연산자 NOT

절차 내용
  7
  0111
NOT ~0111
0111의 2의 보수 1000 + 1
2의 보수 - 1 1000 + 1 - 1
  1000
10진수로 나타내기 1000
  -x -1
  -7 -1
  -8
  0000 0101
^~0000 1100

# 먼저 NOT 연산
~0000 1100
 1111 0011

# 1111 0011을 십진수로 나타내면?
NOT x = -x - 1
NOT 12 = -12 - 1 = -13

# 다시 XOR 연산으로 돌아가면
 0000 0101
^1111 0011
 1111 0110

# 1111 0110을 십진수로 나타내면?
NOT x = -x - 1
x = 0000 1001 = 9
NOT 9 = -9 - 1 = -10