← SEARCHABLE ARCHIVE
Computer Science · 2026-08-14

2의 보수로 음수를 표현하는 이유

부호 있는 정수의 비트 표현과 오버플로 이해하기

INTERACTIVE READING MODE →

본 블로그 작성 글들은, 강의를 목표로 하고 제작되었습니다. 또한 작성된 글의 정보도 틀렸을 수 있으니, 주의해주세요.

컴퓨터는 양수와 음수를 모두 비트로 저장한다. 현대 컴퓨터의 부호 있는 정수는 대부분 2의 보수 방식으로 표현하며, 덧셈 회로를 양수와 음수에 함께 사용할 수 있다는 장점이 있다.

가장 높은 비트가 음수의 가중치를 가진다

4비트 2의 보수 정수를 예로 들면 각 비트의 가중치는 다음과 같다.

비트 위치:    3    2    1    0
가중치:      -8    4    2    1

따라서 0101은 5이고 1101은 다음처럼 -3이 된다.

1101₂ = -8 + 4 + 0 + 1 = -3

n비트 2의 보수 정수의 범위는 -2^(n-1)부터 2^(n-1)-1까지다. 4비트라면 -8부터 7까지이며 음수 쪽이 하나 더 많다.

음수 비트 패턴 만들기

양수의 모든 비트를 뒤집고 1을 더하면 대응하는 음수의 비트 패턴을 얻을 수 있다.

 3       = 0011
비트 반전 = 1100
1 더하기 = 1101 = -3

3 + (-3)을 같은 4비트 덧셈으로 계산하면 다음과 같다.

  0011
+ 1101
------
1 0000

4비트 밖의 올림을 버리면 결과는 0이다. 별도의 뺄셈 표현을 만들지 않고 같은 이진 덧셈 회로로 음수 연산을 처리할 수 있다.

부호 확장

작은 부호 있는 정수를 더 큰 비트 수로 바꿀 때는 가장 높은 부호 비트를 왼쪽에 반복한다.

4비트 -3 :         1101
8비트 -3 :     11111101

앞에 0을 채우면 00001101, 즉 13이 되어 값이 바뀐다. 반대로 부호 없는 정수를 확장할 때는 왼쪽을 0으로 채운다.

오버플로는 비트 해석의 문제다

4비트에서 가장 큰 값 7에 1을 더해보자.

0111 + 0001 = 1000

같은 비트 패턴 1000은 부호 있는 4비트 정수에서 -8이다. 두 양수를 더했는데 음수가 되었으므로 표현 범위를 벗어난 부호 있는 오버플로가 발생했다.

하드웨어 비트 결과가 같아도 프로그래밍 언어의 규칙은 다를 수 있다. C와 C++의 부호 있는 정수 오버플로는 정의되지 않은 동작이고, Java의 고정 폭 정수는 2의 보수 범위로 감싸며, Python의 일반 정수는 필요에 따라 더 큰 크기를 사용한다.

#include <cstdint>
#include <limits>

std::int32_t value = std::numeric_limits<std::int32_t>::max();
// value + 1을 계산하면 C++에서는 정의되지 않은 동작이다.

2의 보수 비트 패턴을 이해하는 것과 언어가 해당 연산을 허용한다는 것은 다른 문제다. 네트워크, 파일, 암호화처럼 정확한 비트 폭이 필요한 코드는 고정 폭 타입과 부호 규칙, 오버플로 정책을 명시해야 한다.