에듀테크 프로젝트 대시보드
비트 연산 (Bitwise Operations)
컴퓨터의 모든 수는 0과 1의 나열(비트)이다. 비트 연산은 이 비트를 한 자리씩 직접 다루는 연산으로, CPU가 딱 한 클럭에 처리할 만큼 빠르다. 권한 플래그, 그래픽 색상, 해시, 암호, 압축 등 밑바닥 코드는 거의 다 비트 연산 위에서 돈다. 아래에서 8비트 수 A·B의 비트를 직접 켜고 끄며 AND · OR · XOR · NOT · Shift 결과를 확인해 보자.
| A | B | A & B AND | A | B OR | A ^ B XOR | ~A NOT |
|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 1 |
| 0 | 1 | 0 | 1 | 1 | 1 |
| 1 | 0 | 0 | 1 | 1 | 0 |
| 1 | 1 | 1 | 1 | 0 | 0 |
한 줄 요약 — AND: 둘 다 1일 때만 1 (필요한 비트만 남기는 마스킹) · OR: 하나라도 1이면 1 (비트 켜기) · XOR: 서로 다를 때만 1 (비트 토글, 같은 값 두 번이면 원상복구) · NOT: 0↔1 반전
리눅스 파일 권한 chmod 755 의 그 원리. 권한 하나 = 비트 하나로 두면
여러 권한을 정수 한 개에 담고, AND/OR로 순식간에 켜고 끄고 검사한다.
웹 색상 #RRGGBB 는 사실 정수 하나다. 8비트씩 3칸을 시프트로 자리에 밀어넣고,
꺼낼 때는 시프트 + AND 0xFF 로 8비트만 잘라낸다.
n & 1 이 1이면 홀수, 0이면 짝수. 마지막 비트만 보면 된다. n % 2 보다 빠르다.
n & (n - 1) == 0 이면 2의 거듭제곱. 1000 & 0111 = 0 처럼 켜진 비트가 딱 1개일 때만 성립.
a^=b; b^=a; a^=b; XOR을 세 번 하면 두 값이 교환된다. (실무에선 가독성 때문에 잘 안 씀)
n &= ~(1 << k) — k번 비트만 0으로. 나머지는 그대로.
켜기 n |= (1 << k) · 검사 (n >> k) & 1 · 토글 n ^= (1 << k)
n << 1 = n×2, n >> 1 = n÷2 (내림). n << 3 = n×8. 컴파일러도 이렇게 최적화한다.
# 권한을 비트로 정의 (플래그는 겹치지 않는 1비트씩) READ, WRITE, EXEC = 0b100, 0b010, 0b001 perm = 0 perm |= READ # 읽기 권한 켜기 -> 0b100 perm |= WRITE # 쓰기 권한 켜기 -> 0b110 has_write = bool(perm & WRITE) # True (AND로 검사) perm &= ~WRITE # 쓰기 권한 끄기 -> 0b100 # RGB 패킹 / 언패킹 def pack(r, g, b): return (r << 16) | (g << 8) | b def unpack(c): return (c >> 16) & 0xFF, (c >> 8) & 0xFF, c & 0xFF color = pack(230, 126, 34) # 15100450 == 0xE67E22 print(hex(color)) # '0xe67e22' -> #E67E22 # 유명한 비트 트릭 is_odd = lambda n: n & 1 is_pow2 = lambda n: n > 0 and n & (n - 1) == 0 count_bits = lambda n: bin(n).count('1') # 켜진 비트 수(popcount)
※ 파이썬 정수는 자릿수 제한이 없어 ~x == -(x+1) 이 되지만, C·자바의 고정폭 정수나
이 페이지의 8비트 데모에서는 ~x 가 그 폭 안에서만 반전된다(2의 보수).
시프트도 부호 있는 음수에서는 언어마다 동작이 다르니 주의.