컴퓨터가 쓰는 진법으로 하는 계산
프로그래머 계산기가 공학용 계산기와 다른 점은 무엇을 기본으로 삼느냐입니다. 2진법, 8진법, 10진법, 16진법을 동시에 다루며 같은 값을 모든 진법으로 한꺼번에 보여 주고, 숫자 전체가 아니라 개별 비트를 조작하는 비트 연산, AND, OR, XOR, NOT, 시프트, 을 제공합니다.
권한 마스크를 읽거나, 색상 값을 확인하거나, 시프트가 왜 예상 밖의 결과를 냈는지 알아낼 때 쓸모 있는 것이 이 조합입니다.
프로그래머 계산기 사용법
결과를 조용히 바꾸는 설정이 워드 크기이므로, 다른 무엇보다 먼저 확인할 가치가 있습니다.
- 워드 크기를 고르세요. 8, 16, 32, 64비트 중에서요. 값이 어디서 넘어가는지와 NOT의 동작을 결정하며, 뜻밖의 결과가 나오는 가장 흔한 원인입니다.
- 편한 진법으로 값을 입력하세요. 나머지 셋이 즉시 갱신되며, 이것이 가장 빠른 변환 방법입니다.
- 마스크와 플래그에는 비트 연산자를 쓰세요. AND는 비트를 검사하거나 지우고, OR은 세우고, XOR은 뒤집습니다.
- 2의 거듭제곱으로 곱하거나 나눌 때는 시프트를 쓰세요. 왼쪽으로 한 칸이면 두 배가 되고, 오른쪽으로 한 칸이면 절반이 되며 끝으로 밀려난 비트는 버려집니다.
- 오버플로를 주의하세요. 워드 크기를 넘는 값은 커지는 대신 한 바퀴 돌아가는데, 실제 코드의 고정 폭 정수에서 일어나는 일이 바로 그것입니다.
워드 크기가 답을 바꾸는 이유
NOT이 가장 분명한 예입니다. 8비트에서 NOT 0은 255입니다. 16비트에서는 65,535, 32비트에서는 4,294,967,295입니다. 연산은 동일하게 모든 비트를 뒤집는 것이지만 비트 수가 다르므로 결과도 다릅니다. NOT이 들어가는 계산이나 범위의 위쪽을 넘나드는 값은 모두 이 설정에 좌우됩니다.
시프트도 같은 민감도를 가집니다. 왼쪽으로 밀면 비트가 워드의 위쪽으로 밀려나 사라지므로, 0x80을 왼쪽으로 한 칸 밀면 16비트에서는 0x100이지만 8비트에서는 0x00입니다. 이는 계산기의 특이 동작이 아니라 C, 자바, 러스트의 고정 폭 정수에서 정확히 일어나는 일이며, 디버깅 중인 타입에 워드 크기를 맞춰야 하는 이유입니다.
비트 연산
각 연산자가 하는 일과, 대개 어떤 작업에 쓰이는지입니다.
| 연산자 | 효과 | 주요 용도 |
|---|---|---|
| AND (&) | 두 비트가 모두 1일 때만 1 | 플래그 검사, 마스크로 비트 지우기 |
| OR (|) | 한쪽이라도 1이면 1 | 다른 비트를 건드리지 않고 플래그 세우기 |
| XOR (^) | 두 비트가 다르면 1 | 비트 뒤집기, 간단한 체크섬 |
| NOT (~) | 모든 비트를 반전 | 역마스크 만들기 |
| << (왼쪽 시프트) | 한 칸마다 2를 곱함 | 빠른 곱셈, 마스크 생성 |
| >> (오른쪽 시프트) | 한 칸마다 2로 나눔 | 빠른 나눗셈, 비트 필드 추출 |
마스크와의 AND는 묶여 있는 값의 일부를 읽어내는 방법입니다. RGB 색상 0xFF8800에서 초록 채널은 (값 >> 8) & 0xFF로 얻습니다. 자리로 밀고 나서 마스크를 씌우는 이 패턴이 비트 조작에서 가장 흔한 관용구입니다.
일상적인 개발에서의 진법
16진법이 지배적인 이유는 한 자리가 정확히 4비트에 대응하기 때문입니다. 그래서 1바이트는 언제나 16진수 두 자리이고 경계가 한눈에 보입니다. 2진법은 개별 비트를 보여 주지만 1~2바이트를 넘어가면 읽을 수 없게 됩니다. 8진법은 주로 유닉스 파일 권한에 살아남았는데, 한 자리가 한 사용자 부류의 읽기·쓰기·실행을 깔끔하게 담기 때문입니다.
chmod 755가 그런 뜻인 이유가 여기 있습니다. 7은 2진수로 111이라 소유자에게 읽기·쓰기·실행을 주고, 5는 101이라 그룹과 그 외에 읽기·실행을 줍니다. 계산기에서 8진수와 2진수를 나란히 보면 10진수 493으로는 결코 드러나지 않는 이 대응이 명확해집니다.