CS/algorithm & data structure
[파이썬 알고리즘 인터뷰] 비트 조작
hjkim0502
2022. 5. 4. 21:05
- 부울 연산자: NOT, AND, OR (기본), XOR (보조)
- 기본 연산자를 조합해 보조 연산 가능
- XOR: TT, FF 일때는 F 반환, TF, FT 일때는 T 반환
# XOR
x = y = True
(x and not y) or (not x and y)
>>> False
- 비트 연산자
- ~ : (2의 보수) - 1, 십진수로는 -x-1, 부울 변수 True에 적용하면 -1-1 = -2
True & False # Bitwise AND
>>> False
True | False # Bitwise OR
>>> True
True ^ True # Bitwise XOR
>>> False
~ True # Bitwise NOT
>>> -2
# 십진수와 마찬가지로 연산
bin(0b0110 + 0b0010)
>>> '0b1000'
bin(0b0011 * 0b0101)
>>> '0b1111'
# 시프팅
bin(0b1101 >> 2)
>>> '0b11'
bin(0b1101 << 2)
>>> '0b110100'
# 밑에서 설명
bin(0b0101 ^ ~0b1100)
>>> '-0b1010' # 0b0110
- 우리가 예상한 0b0110이 나오려면 ~0b1100이 0b0011이 되어야 하는데, 컴퓨터는 그렇게 계산하지 않음
- 자릿수 만큼의 최댓값을 지닌 MASK를 만들고 그 값과 XOR 연산해야 예상대로 진행됨
- 0b1100 ^ 0b1111 하면 0b0011
# 자릿수 제한 비트 연산
MASK = 0b1111
bin(0b0101 ^ (0b1100 ^ MASK))
>>> '0b110'
- 파이썬의 진법 표현
# 이진수(binary) ↔ 십진수 (decimal)
bin(87) # '0b1010111'
int('0b1010111', 2) # 87
int('1010111', 2) # 87
a = 87
b = 0b1010111
b # 87
# 16진수 (hexadecimal) ↔ 십진수
hex(87) # '0x57'
c = 0x57
c # 87
# id(a) = id(b) = id(c)
- 16진수로 10 ~ 15는 A ~ F로 표현
- 2의 보수: 컴퓨터가 음수를 저장하기 위해 일반적으로 취하는 여러 방법 중 하나
- 4비트로 숫자 표현 가정: 16개 숫자 표현 가능
- 양수만 표현한다면 0000 ~ 1111 (0 ~ 15)
- 음수도 저장한다면 맨 앞 비트는 부호비트 -> 양수는 0xxx, 음수는 1xxx
- n비트일 때 표현 범위는 -2^(n-1) ~ 2^(n-1) - 1
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 |
-1 | -2 | -3 | -4 | -5 | -6 | -7 | -8 |
1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 |
# 십진수 x를 4비트 2의 보수로 표현
# 2^4 = 16^1이므로 F한개
MASK = 0xF
bin(x & MASK)
- 파이썬은 내부적으로 비트 연산이 필요할 때만 2의 보수로 변환하는 작업 수행, 실제 2의 보수 값 보여주진 않음
- 숫자를 4비트로 표현하든 32비트로 표현하든 비트 연산 결과 동일
- 십진수 -> n비트 2의 보수 -> 비트 연산 -> 십진수
- 비트 연산자 NOT (~): 십진수를 2의 보수로 표현 후 1 뺀 것
- 기준 비트 내에서 정확히 1을 0으로, 0을 1로 바꿔줌 (2의 보수 포맷)
- ~ x = -x - 1 (십진수 포맷)
- 2의 보수 수학 연산: 십진수를 2의 보수로 표현 후 ~ 연산하고 1 더한 것
- 양수를 음수로, 음수를 양수로 바꾸는 연산 (십진수 포맷)
- ex) 7 -> 0111 -> 1000(=~0111) -> 1001
- 0111 + 1001 = 10000 -> 0000 (4비트 연산이므로 초과한 자릿수 무시)
136. Single Number
- 배열의 모든 값 XOR -> 0 ^ x(십진수) = x, 교환/결합법칙 성립
- a ^= b ↔ a = a ^ b
461. Hamming Distance
- XOR 연산 후 이진수 포맷에서 1 개수
371. Sum of Two Integers
- 전가산기 구현
* 마스킹은 십진수끼리
- zfill(), rjust()
393. UTF-8 Validation
- 첫 바이트로 이후 바이트 형태 판별하는 과정 반복
191. Number of 1 Bits
- count()
- n &= n - 1 -> n 과 n - 1 을 AND 연산하면 1비트씩 빠진다
- XOR을 이용한 변수 스왑
x, y = 9, 4
x = x ^ y
y = x ^ y
x = x ^ y
x, y
>>> (4, 9)