---
title: "2의 보수: 같은 덧셈 회로로 음수까지 계산하는 표현"
author: "Lee"
published_at: "2026-10-28T04:46:01.577Z"
updated_at: "2026-09-30T09:54:44.971Z"
tags: ["컴퓨터공학","컴퓨터구조"]
canonical_url: "https://ariser.io/@writer_a1cd615ab19e/2%EC%9D%98-%EB%B3%B4%EC%88%98-%EA%B0%99%EC%9D%80-%EB%8D%A7%EC%85%88-%ED%9A%8C%EB%A1%9C%EB%A1%9C-%EC%9D%8C%EC%88%98%EA%B9%8C%EC%A7%80-%EA%B3%84%EC%82%B0%ED%95%98%EB%8A%94-%ED%91%9C%ED%98%84"
ai_assisted: false
---

# 2의 보수: 같은 덧셈 회로로 음수까지 계산하는 표현

[원문](https://ariser.io/@writer_a1cd615ab19e/2%EC%9D%98-%EB%B3%B4%EC%88%98-%EA%B0%99%EC%9D%80-%EB%8D%A7%EC%85%88-%ED%9A%8C%EB%A1%9C%EB%A1%9C-%EC%9D%8C%EC%88%98%EA%B9%8C%EC%A7%80-%EA%B3%84%EC%82%B0%ED%95%98%EB%8A%94-%ED%91%9C%ED%98%84)

고정된 n비트로 양수와 음수를 함께 표현할 때 널리 쓰는 방법이 2의 보수다. 최상위 비트가 양수의 크기에 더해지는 대신 음의 가중치를 가진다고 해석하면 값을 계산할 수 있다. n비트의 범위는 -2^(n-1)부터 2^(n-1)-1까지다. 음수가 하나 더 많아 범위가 비대칭이며, 0은 한 가지 패턴으로 표현된다.

![8비트 5의 비트를 뒤집고 1을 더해 -5인 11111011을 얻는 과정과 -128부터 127까지의 범위](/api/v1/media/53ea6318-d2e9-43ac-85cd-7fd065a7d531)

*고정 비트 폭과 부호 해석을 함께 정해야 2의 보수 패턴의 값을 읽을 수 있다.*

## -5를 8비트로 만드는 과정

8비트의 5는 `00000101`이다. 모든 비트를 뒤집으면 `11111010`, 여기에 1을 더하면 `11111011`이 된다. 이 패턴을 2의 보수로 읽으면 -5다. 뒤집고 1을 더하는 방법은 고정 폭에서 덧셈의 역원을 얻는 절차다. 단순히 맨 앞에 부호 비트를 붙이는 부호와 크기 표현과는 다르다.

가중치로 확인하면 최상위 비트는 -128이고 나머지는 64+32+16+8+2+1이므로 합계 -5가 된다. 같은 패턴을 부호 없는 8비트 정수로 해석하면 251이다. 비트 자체가 부호를 지닌다기보다 타입과 연산 규칙이 패턴의 의미를 정한다. [Java의 정수 타입 규정](https://docs.oracle.com/javase/specs/jls/se24/html/jls-4.html)은 byte·short·int·long을 지정한 폭의 부호 있는 2의 보수 값으로 정의한다.

## 덧셈을 같은 비트 연산으로 한다

8비트에서 5와 -5의 패턴을 더하면 아홉 번째 자리로 넘어가는 올림이 생기고, 아래 여덟 비트는 모두 0이 된다. 고정 폭 비트 덧셈을 모듈러 산술로 보는 관점이다. 덧셈 회로의 구조를 음수 전용으로 새로 만들지 않고도 부호 정수 계산에 사용할 수 있다. 그러나 산술 결과가 표현 범위 안인지 확인하는 오버플로 판단은 별도의 문제다.

예를 들어 8비트 부호 정수 모델에서 127에 1을 더한 아래 비트는 `10000000`이 되어 -128로 해석된다. 실제 수학적 합 128은 범위 밖이다. 부호 없는 올림과 부호 있는 오버플로는 같은 조건이 아니다. 같은 부호의 두 수를 더했는데 결과 부호가 바뀌는 경우 등이 부호 오버플로 판단의 출발점이 된다.

## 가장 작은 음수의 특이점

8비트 범위는 -128부터 127이다. -128의 양수 대응인 128은 같은 부호 타입으로 표현할 수 없다. 그래서 가장 작은 음수에 단순히 음수를 취하는 연산이 범위 문제를 만들 수 있다. 절댓값 함수나 부호 변환에서 이 경계 조건을 놓치면 일반적인 작은 입력에서는 보이지 않는 오류가 생긴다.

폭을 늘릴 때는 부호 확장을 사용한다. -5의 8비트 패턴 앞에 최상위 1을 반복해 16비트 `1111111111111011`로 만들면 값이 유지된다. 양수는 앞에 0을 붙인다. 부호 없는 값의 0 확장과 구분해야 하며, 좁은 타입으로 줄일 때는 일부 비트가 잘리므로 원래 값이 항상 유지되지 않는다.

언어마다 범위 밖 연산의 의미가 다르다. 일부 언어의 고정 폭 정수는 정해진 래핑을 제공하지만 C나 C++의 부호 있는 오버플로는 단순 래핑으로 가정할 수 없다. Python의 일반 정수처럼 임의 정밀도를 제공하는 경우도 있다. CPU의 비트 표현과 언어의 연산 계약을 함께 확인해야 한다.

2의 보수는 음수 표현, 부호 확장, 비트 덧셈을 하나의 규칙으로 연결한다. 메모리 덤프에서 큰 부호 없는 숫자가 작은 음수와 같은 패턴인 이유도 설명한다. 계산할 때는 비트 폭, 부호 해석, 범위 밖 동작을 항상 같이 적는 습관이 중요하다.

### 참고 자료

- [Java Language Specification — Integral Types and Values](https://docs.oracle.com/javase/specs/jls/se24/html/jls-4.html)
