본문 바로가기

음수·보수·넘침

부호 크기·1의 보수·2의 보수를 비교하고 부호 확장과 부호 있는 넘침을 판단합니다.

온도 센서에는 영하 값도 필요합니다. 맨 앞 비트를 부호로 쓰는 것만으로는 덧셈 회로를 편리하게 재사용하기 어렵습니다. 음수를 어떻게 표현하느냐가 연산 규칙까지 바꿉니다.

세 방식의 차이

4비트에서 +3은 0011입니다. 부호 크기 방식은 최상위 비트에 부호, 나머지에 크기를 넣어 -3을 1011로 표현합니다. 1의 보수는 모든 비트를 반전해 1100을 얻습니다. 2의 보수는 반전한 뒤 1을 더해 1101을 얻습니다.

방식+0·-04비트 범위-3
부호 크기0000·1000-7~+71011
1의 보수0000·1111-7~+71100
2의 보수0000 한 가지-8~+71101

1의 보수 덧셈은 끝 자리올림을 하위 자리에 되돌리는 규칙을 사용합니다. 현대 정수 CPU를 설명하는 이 교재의 기본 모델은 2의 보수입니다. 세 방식을 섞어서 계산하지 마세요.

2의 보수를 해석하는 두 방법

4비트 패턴 u를 부호 없는 값으로 읽었을 때, 맨 앞이 0이면 그대로입니다. 맨 앞이 1이면 u - 16으로 읽습니다. 1101은 13-16=-3, 1000은 8-16=-8입니다. 일반적으로 n비트 2의 보수 범위는 -2ⁿ⁻¹~2ⁿ⁻¹-1입니다.

최상위 비트의 가중치를 음수로 생각해도 됩니다. 1101은 -8+4+0+1=-3입니다. 범위의 음수 쪽에 값이 한 개 더 많은 이유도 -8 자리에 양수 +8 패턴이 없기 때문입니다.

덧셈과 뺄셈

4비트에서 5+(-3)은 0101 + 1101 = 10010입니다. 하위 4비트 0010이 2이고, 버린 자리올림은 1입니다. 이 경우 자리올림이 있어도 부호 있는 결과는 정확합니다.

반대로 5+4는 0101 + 0100 = 1001입니다. 부호 있는 결과는 -7로 해석되므로 넘침입니다. 자리올림은 0입니다. 같은 부호의 두 값을 더했는데 결과 부호가 달라지면 부호 있는 오버플로우입니다. 다른 부호끼리의 덧셈은 범위를 넘지 않습니다.

뺄셈 a-b는 a+(-b)로 계산합니다. 다만 가장 작은 음수의 부호를 반전한 값은 같은 폭으로 표현할 수 없습니다. 4비트 -8의 부호를 반전하려고 2의 보수를 취하면 다시 1000이 됩니다. 수학적 +8을 저장하지 못한 것입니다.

폭을 늘릴 때

부호 확장(sign extension)은 2의 보수 값을 더 넓게 옮길 때 최상위 비트를 복제합니다. 4비트 -3 1101을 8비트로 옮기면 11111101입니다. 앞에 0을 붙인 00001101은 +13이므로 값이 달라집니다. 부호 없는 값에는 0 확장을 사용합니다.

def signed(pattern, width):
    if not 0 <= pattern < (1 << width):
        raise ValueError("패턴이 폭을 벗어났습니다")
    return pattern if pattern < (1 << (width - 1)) else pattern - (1 << width)

assert signed(0b1101, 4) == -3
assert signed(0b11111101, 8) == -3
assert signed((5 + 4) & 0b1111, 4) == -7
assert signed((5 + 13) & 0b1111, 4) == 2

독립 문제: 두 종류의 넘침

4비트 덧셈기에서 1110 + 0011을 계산하세요. 부호 없는 입력 해석과 2의 보수 입력 해석에서 각각 수학 결과·저장 값·넘침 여부를 쓰세요. 이어 8비트 -6의 패턴을 구하세요.

힌트

1110은 해석에 따라 14 또는 -2입니다. 회로에 들어가는 비트는 동일합니다.

풀이와 오개념

비트 합은 10001, 저장 패턴은 0001, 자리올림은 1입니다. 부호 없는 계산은 14+3=17을 표현하지 못하므로 넘칩니다. 부호 있는 계산은 -2+3=1로 정확합니다. -6은 +6 00000110을 반전하고 1을 더해 11111010입니다.

“최상위 비트는 언제나 부호”라는 말은 해석을 생략합니다. 부호 없는 주소에서도 최상위 비트가 1일 수 있습니다. 이 차이가 헷갈리면 고정 폭 정수를 복습하세요.