Skip to main content
KO
guide

Complete Number Base Conversion Guide — Understanding Binary, Octal, Decimal, Hexadecimal

2026-04-13 · 10 min read

진법이란? — 왜 10진수 외에 다른 진법이 필요한가

우리가 일상에서 숫자를 셀 때 0부터 9까지 10개의 숫자를 사용합니다. 9 다음에는 자릿수를 올려 10이 됩니다. 이것이 바로 **10진법(decimal)**이며, 인류가 손가락 10개를 가지고 있기 때문에 자연스럽게 발전한 수 체계입니다.

하지만 컴퓨터의 세계에서는 사정이 다릅니다. 전자 회로는 전기 신호의 켜짐(1)꺼짐(0) 두 가지 상태만 구분합니다. 따라서 컴퓨터가 처리하는 모든 데이터는 궁극적으로 0과 1의 조합, 즉 **2진법(binary)**으로 표현됩니다.

그런데 2진수는 자릿수가 매우 길어서 사람이 읽고 쓰기 불편합니다. 예를 들어 10진수 255를 2진수로 표현하면 11111111로 8자리나 됩니다. 이를 보완하기 위해 프로그래머들은 **16진법(hexadecimal)**과 **8진법(octal)**을 함께 사용합니다.

각 진법이 사용하는 숫자 범위를 정리하면 다음과 같습니다.

진법기수사용 숫자예시
2진법20, 11010
8진법80–712
10진법100–910
16진법160–9, A–FA

2진수 기초 — 컴퓨터가 2진수를 쓰는 이유

컴퓨터가 2진수를 사용하는 근본적인 이유는 하드웨어 설계의 단순함입니다. 트랜지스터는 전압의 높고 낮음으로 두 가지 상태를 안정적으로 표현할 수 있습니다. 이 두 상태가 곧 0과 1입니다.

2진수의 각 자리를 **비트(bit)**라고 부르며, 8비트가 모이면 **바이트(byte)**가 됩니다. 1바이트로 표현할 수 있는 범위는 0(00000000)부터 255(11111111)까지 총 256가지입니다.

2진수를 10진수로 변환하는 방법은 각 자릿수에 2의 거듭제곱을 곱하여 합산하는 것입니다.

1101(2) = 1×2³ + 1×2² + 0×2¹ + 1×2⁰
        = 8 + 4 + 0 + 1
        = 13(10)

반대로 10진수를 2진수로 바꿀 때는 2로 반복해서 나누고 나머지를 역순으로 읽습니다.

13 ÷ 2 = 6 ... 나머지 1
 6 ÷ 2 = 3 ... 나머지 0
 3 ÷ 2 = 1 ... 나머지 1
 1 ÷ 2 = 0 ... 나머지 1
→ 1101(2)

16진수 — 색상 코드, 메모리 주소, 그리고 그 이상

16진법은 0부터 9까지의 숫자와 A(10)부터 F(15)까지의 알파벳을 사용하여 한 자리에 16가지 값을 표현합니다. 16진수의 가장 큰 장점은 2진수와의 깔끔한 대응 관계입니다.

16진수 한 자리는 정확히 **4비트(2진수 4자리)**에 대응합니다. 따라서 1바이트(8비트)는 16진수 2자리로 표현할 수 있습니다.

2진수:  1111 1010
16진수:    F    A
→ 0xFA

웹 개발에서의 16진수: 색상 코드

CSS 색상 코드 #FF5733은 16진수로 표현된 RGB 값입니다.

  • FF = 빨간색 255 (최대)
  • 57 = 초록색 87
  • 33 = 파란색 51

메모리 주소

디버깅이나 시스템 프로그래밍에서 메모리 주소는 관습적으로 16진수로 표시합니다. 0x7FFFFFFF처럼 0x 접두사를 붙여 16진수임을 나타냅니다. 32비트 주소를 2진수로 쓰면 32자리나 되지만, 16진수로는 8자리로 간결하게 표현됩니다.

MAC 주소와 IPv6

네트워크에서 장치를 식별하는 MAC 주소(00:1A:2B:3C:4D:5E)도 16진수입니다. IPv6 주소(2001:0db8:85a3::8a2e:0370:7334)도 128비트를 16진수로 표기합니다.


8진수 — 파일 권한과 chmod

8진법은 0부터 7까지의 숫자를 사용하며, 한 자리가 정확히 3비트에 대응합니다. 현대 프로그래밍에서 8진수가 가장 자주 등장하는 곳은 Unix/Linux 파일 권한입니다.

chmod 755 script.sh

여기서 755는 8진수로, 각 자리가 소유자/그룹/기타 사용자의 읽기(4)+쓰기(2)+실행(1) 권한을 나타냅니다.

  • 7 = 4+2+1 = rwx (읽기+쓰기+실행)
  • 5 = 4+0+1 = r-x (읽기+실행)
  • 5 = 4+0+1 = r-x (읽기+실행)

2진수로 풀어보면 111 101 101이 되어 각 비트가 하나의 권한 플래그에 대응합니다.


수동 변환 방법 정리

10진수 → N진수

10진수를 목표 진법의 기수로 반복해서 나누고, 나머지를 역순으로 읽습니다.

100(10) → 16진수
100 ÷ 16 = 6 ... 나머지 4
  6 ÷ 16 = 0 ... 나머지 6
→ 64(16)

N진수 → 10진수

각 자릿수에 기수의 거듭제곱을 곱해 합산합니다.

64(16) = 6×16¹ + 4×16⁰ = 96 + 4 = 100(10)

2진수 ↔ 16진수 (빠른 변환)

2진수를 오른쪽부터 4자리씩 묶으면 각 그룹이 16진수 한 자리에 대응합니다.

1010 1100(2) = A C(16) = 0xAC

2진수 ↔ 8진수 (빠른 변환)

2진수를 오른쪽부터 3자리씩 묶으면 각 그룹이 8진수 한 자리에 대응합니다.

101 100(2) = 5 4(8) = 0o54

프로그래밍 언어별 진법 표기법

대부분의 현대 프로그래밍 언어는 리터럴 접두사로 진법을 표기합니다.

진법접두사예시지원 언어
2진수0b 또는 0B0b1010JavaScript, Python, Java, C++, Go, Rust
8진수0o 또는 0O0o12JavaScript, Python, Go, Rust
8진수0 (레거시)012C, C++, Java (주의: 실수 유발)
16진수0x 또는 0X0xFF거의 모든 언어

JavaScript에서의 활용 예시를 보겠습니다.

const dec = 255;
const bin = 0b11111111;  // 255
const oct = 0o377;       // 255
const hex = 0xFF;        // 255

// 변환 메서드
dec.toString(2);   // "11111111"
dec.toString(8);   // "377"
dec.toString(16);  // "ff"

// 파싱
parseInt("ff", 16);  // 255
parseInt("377", 8);  // 255
parseInt("11111111", 2);  // 255

Python에서도 마찬가지로 내장 함수를 제공합니다.

bin(255)  # '0b11111111'
oct(255)  # '0o377'
hex(255)  # '0xff'

int('ff', 16)  # 255
int('377', 8)  # 255

주의할 점은 C와 Java에서 8진수 접두사 0입니다. 012는 10이 아니라 8진수 10, 즉 10진수 10이 됩니다. 이런 혼동을 피하기 위해 최신 언어들은 0o 접두사를 채택하고 있습니다.


음수 표현: 2의 보수

컴퓨터에서 음수를 표현하는 표준 방식은 **2의 보수(two’s complement)**입니다. 최상위 비트(MSB)가 부호 비트로 사용되어, 0이면 양수, 1이면 음수를 나타냅니다.

8비트에서 -1을 표현하는 과정을 보겠습니다.

+1   = 00000001
비트 반전 = 11111110
+1       = 11111111  → 이것이 -1의 2의 보수 표현

8비트 signed 범위는 -128(10000000)에서 +127(01111111)입니다. unsigned로는 같은 8비트가 0에서 255를 표현합니다.


QuickToolkit 진법 변환기 활용하기

수동 변환 방법을 이해했다면, 실무에서는 도구를 활용하는 것이 훨씬 효율적입니다. 진법 변환기를 사용하면 2진수, 8진수, 10진수, 16진수를 실시간으로 상호 변환할 수 있습니다.

특히 비트 시각화 기능은 숫자가 메모리에 실제로 어떤 비트 패턴으로 저장되는지를 직관적으로 보여주며, signed/unsigned 모드를 전환하면 같은 비트 패턴이 부호에 따라 어떻게 다르게 해석되는지 확인할 수 있습니다.

해시 함수에서 사용되는 16진수 표현이 궁금하다면 해시 함수 보안 가이드도 함께 읽어 보세요.