대규모 MMO 서버 개발에서는 캐릭터 상태(기절, 무적, 은신 등) 여러 개를 각각 별도의 불리언 변수로 두지 않고 정수 하나의 비트마다 하나씩 배정하는 경우가 흔하다. 특정 상태가 활성화되어 있는지 확인하는 건 AND 연산 한 번으로 끝나며, 네트워크로 전송할 상태 데이터의 크기도 훨씬 줄어든다.
AND, OR, XOR, NOT — 네 가지 기본 연산
- AND (&) — 입력 비트 두 개가 모두 1일 때만 결과 비트가 1입니다. 상태 마스크에서 특정 플래그가 켜져 있는지 확인할 때 씁니다.
- OR (|) — 입력 비트 중 적어도 하나가 1이면 결과 비트가 1입니다. 여러 상태 플래그를 하나의 값으로 합칠 때 씁니다.
- XOR (^) — 입력 비트가 서로 다르면 결과 비트가 1입니다. 같은 값으로 XOR을 두 번 적용하면 원래 값으로 돌아옵니다.
- NOT (~) — 숫자의 모든 비트를 반전시킵니다.
비트 AND가 논리 AND와 다른 점
논리 AND(대부분의 언어에서 &&)는 불리언 값 전체에 작동해 true/false를 반환하는 반면, 비트 AND(&)는 두 숫자의 각 비트를 개별적으로 처리해 숫자를 반환합니다. 이 둘을 혼동하는 것이 흔한 버그 원인이며, 일부 언어에서는 타입 에러조차 없이 둘 다 컴파일되기 때문에 더 위험합니다.
이 도구가 진법 변환기와 짝을 이루는 이유
상태 마스크 값이 10진수 18이면 어떤 플래그가 켜져 있는지 한눈에 알기 어렵지만, 같은 값을 0b10010으로 표기하면 어떤 비트가 켜져 있는지 즉시 보입니다. 비트 연산은 거의 항상 10진법이 아니라 2진법이나 16진법으로 사고되는데, AND·OR·XOR이 시각적으로 의미를 가지려면 대개 진법 변환이 먼저 필요합니다.
왜 필요한가
- 불리언 플래그 여러 개를 숫자 하나에 효율적으로 저장하고 확인하기.
- 네트워크 프로토콜이나 바이너리 형식을 다루는 저수준 코드 이해하기.
- 비트 연산이 일반 산술보다 빠른 계산 최적화하기.
연산자 우선순위의 함정
대부분의 프로그래밍 언어에서 비트 연산자 &와 |는 비교 연산자보다 우선순위가 낮습니다 — 따라서 if (a & b == c)와 같은 표현식은 작성자가 의도한 것이 아니라 실제로는 a & (b == c)로 계산됩니다. 이는 비트 마스크를 다룰 때 발견하기 어려운 버그의 가장 흔한 원인 중 하나이며, 이를 피하는 확실한 방법은 비트 연산 주위에 항상 명시적으로 괄호를 두는 것입니다.