왜 여러 수 체계가 존재하는가?
인간은 손가락이 10개이기 때문에 10진수(십진법)로 셉니다. 컴퓨터는 켜짐/꺼짐 두 가지 상태를 가진 트랜지스터로 만들어졌기 때문에 2진수(이진법)가 자연스럽습니다. 프로그래머들은 이진수를 압축적으로 표현하기 위해 16진수(십육진법)를 씁니다. 8진수(팔진법)는 파일 권한과 옛 컴퓨팅 환경에서 등장합니다.
이 수 체계들을 이해하면 많은 기술 문서, 프로그래밍 개념, 저수준 컴퓨팅이 이해됩니다.
십진수: 우리가 이미 아는 것
십진수에서 각 자릿값은 10의 거듭제곱을 나타냅니다. 숫자 3,742는: - 3 × 10³ = 3,000 - 7 × 10² = 700 - 4 × 10¹ = 40 - 2 × 10⁰ = 2 - 합계: 3,742
이 위치 기반 값 원리는 모든 수 체계에 적용됩니다. 달라지는 것은 기수(밑)뿐입니다.
이진수: 기수 2
이진수는 0과 1, 두 가지 숫자만 사용합니다. 각 자릿값은 2의 거듭제곱을 나타냅니다.
이진수 1011의 의미: - 1 × 2³ = 8 - 0 × 2² = 0 - 1 × 2¹ = 2 - 1 × 2⁰ = 1 - 합계: 십진수 11
**십진수 → 이진수 변환:** 2로 반복 나누며 나머지를 기록합니다. 25를 변환하면: - 25 ÷ 2 = 12 나머지 **1** - 12 ÷ 2 = 6 나머지 **0** - 6 ÷ 2 = 3 나머지 **0** - 3 ÷ 2 = 1 나머지 **1** - 1 ÷ 2 = 0 나머지 **1** 나머지를 아래에서 위로 읽으면: **11001** (= 16 + 8 + 1 = 25 ✓)
컴퓨터는 텍스트, 이미지, 오디오, 코드 모두를 이진수로 저장합니다. 비트 하나가 0이나 1입니다. 8비트가 1바이트를 구성하고, 256가지 값(0~255)을 표현할 수 있습니다.
십육진수(헥사): 기수 16
16진수는 0~9와 A~F(A=10, B=11, C=12, D=13, E=14, F=15)의 16가지 기호를 사용합니다. 16진수는 각 16진수 숫자가 정확히 4비트 이진수에 대응하기 때문에 프로그래머들이 선호합니다.
16진수 `2F`의 의미: - 2 × 16¹ = 32 - F(15) × 16⁰ = 15 - 합계: 십진수 47
**프로그래머들이 16진수를 좋아하는 이유:** 1바이트(8비트)를 정확히 두 자리 16진수로 표현할 수 있습니다. 이진수 11001111 = 16진수 CF. `0xFF`가 `11111111`보다 훨씬 간결하고, 오탈자 오류도 훨씬 적습니다.
컴퓨팅에서 16진수를 자주 만납니다: - **CSS 색상:** `#FF5733`은 FF(255) 빨강, 57(87) 초록, 33(51) 파랑 - **메모리 주소:** 디버거와 어셈블리에서 `0x00401234` - **MAC 주소:** `00:1A:2B:3C:4D:5E` — 6쌍의 16진수 - **SHA-256 해시:** 256비트 값을 나타내는 64개의 16진수 문자 - **유니코드 코드 포인트:** U+1F600은 이모지 😀
프로그래밍에서 `0x` 접두사는 16진수 리터럴을 나타냅니다. `0b`는 이진수, `0o`는 8진수입니다.
팔진수: 기수 8
8진수는 0~7의 숫자를 사용합니다. 주로 유닉스/리눅스 파일 권한에서 등장합니다.
터미널에서 `chmod 755`를 실행하면, 각 숫자는 권한 집합을 나타내는 8진수입니다: - 7 = 이진수 111 = 읽기(4) + 쓰기(2) + 실행(1) - 5 = 이진수 101 = 읽기(4) + 실행(1)
따라서 `755`는: 소유자가 전체 권한(rwx), 그룹과 기타 사용자는 읽기와 실행만 가능(r-x)을 의미합니다.
진법 간 변환
**이진수 → 16진수:** 이진수를 오른쪽부터 4자리씩 묶은 후, 각 그룹을 16진수 한 자리로 변환합니다. 11011010 → 1101 | 1010 → D | A → `0xDA` (= 십진수 218)
**16진수 → 이진수:** 각 16진수 자리를 4비트 이진수로 교체합니다. `0xB7` → 1011 | 0111 → 10110111
**임의 진법 → 십진수:** 각 자리에 자릿값(기수^자리 위치)을 곱하고 합산합니다.
**십진수 → 임의 진법:** 목표 기수로 반복 나누며 나머지를 기록하고, 아래에서 위로 읽습니다.
비트 연산
비트 연산은 정수의 이진수 표현에 직접 작용합니다. 저수준 프로그래밍, 암호화, 네트워크 프로토콜의 기본입니다.
- **AND (&):** 두 입력 비트가 모두 1일 때만 1. 비트 마스킹에 사용.
- **OR (|):** 한 입력 비트라도 1이면 1. 비트 설정에 사용.
- **XOR (^):** 입력 비트가 다를 때 1. 암호화에 사용.
- **NOT (~):** 모든 비트를 뒤집습니다.
- **왼쪽 시프트 (<<):** 비트를 왼쪽으로 이동, 자리마다 2를 곱함. 5 << 1 = 10.
- **오른쪽 시프트 (>>):** 비트를 오른쪽으로 이동, 자리마다 2로 나눔. 8 >> 1 = 4.
이 연산들을 이해하면 효율적인 저수준 코드 작성, 네트워크 서브넷 계산 구현, 암호화 알고리즘이 비트 수준에서 어떻게 동작하는지 이해하는 데 필수적입니다.