컴퓨터의 음수표현과 2의 보수
컴퓨터의 음수 표현
컴퓨터는 모든 데이터를 0과 1로 표현한다. 2진수에 대해서 알고 있다면 양수로 이루어진 자연수를 표현할 때 큰 어려움 없이 표현할 수 있다. 예를 들어 5라는 10진수 숫자를 2진수로 표현하면 101(2)이다.
그렇다면 -5라는 숫자를 표현할 때는 어떻게 해야 할까? 단순하게 생각하면 -를 붙여서 -101로 표현하면 되지 않을까 생각할 수 있다. 하지만 앞서 말했듯 컴퓨터는 모든 데이터를 0과 1로 표현하기 때문에 -라는 부호를 이해하지 못한다.
음수를 표현하는 방법 (1): 부호-크기(Sign-Magnitude)
음수를 표현하는 가장 간단한 방법은 부호-크기(Sign-Magnitude) 방식이다. 이 방식은 부호를 별도로 표현하는 방법이다.
- 가장 왼쪽 비트(최상위 비트)를 부호로 사용한다.
0이면 양수,1이면 음수
- 나머지 비트는 숫자의 크기를 나타낸다.
즉, +와 -를 각각 0과 1로 표현하는 방식이다.
부호-크기 방식에서 n비트로 표현할 수 있는 숫자의 범위는 부호 비트를 제외한 n-1비트로 결정된다. 따라서 표현 가능한 범위는 \(-(2^{n-1}-1) \sim 2^{n-1}-1\) 이 된다.
4비트의 숫자를 부호-크기 방식으로 표현하면 다음과 같다.
| 10진수 | 2진수 |
|---|---|
| +7 | 0111 |
| +6 | 0110 |
| +5 | 0101 |
| +4 | 0100 |
| +3 | 0011 |
| +2 | 0010 |
| +1 | 0001 |
| +0 | 0000 |
| -0 | 1000 |
| -1 | 1001 |
| -2 | 1010 |
| -3 | 1011 |
| -4 | 1100 |
| -5 | 1101 |
| -6 | 1110 |
| -7 | 1111 |
하지만 이 방법에는 몇 가지 문제가 있다.
+0과-0이 존재하여0을 표현하는 방법이 두 가지이다 (0000,1000).- 뺄셈 연산이 복잡해진다.
음수를 표현하는 방법 (2): 1의 보수(1’s Complement)
부호-크기 방식의 문제점을 보완하기 위해 나온 방법이 1의 보수(1’s Complement) 방식이다.
1의 보수란 어떤 2진수의 모든 비트를 반전시키는 것을 말한다. 즉, 0은 1로, 1은 0으로 바꾸는 것이다.
- 양수는 기존과 동일하게 표현한다.
- 음수는 해당 숫자의 이진수를 비트 반전하여 나타낸다.
예를 들어, 5는 0101이며, -5는 0101의 모든 비트를 반전한 1010이다.
4비트의 숫자를 1의 보수로 표현하면 다음과 같다.
| 10진수 | 2진수 |
|---|---|
| +7 | 0111 |
| +6 | 0110 |
| +5 | 0101 |
| +4 | 0100 |
| +3 | 0011 |
| +2 | 0010 |
| +1 | 0001 |
| +0 | 0000 |
| -0 | 1111 |
| -1 | 1110 |
| -2 | 1101 |
| -3 | 1100 |
| -4 | 1011 |
| -5 | 1010 |
| -6 | 1001 |
| -7 | 1000 |
1의 보수를 사용하면 부호-크기 방식보다 뺄셈 연산이 간단해진다. 뺄셈 대신 덧셈을 수행하고, 최상위 비트에서 발생하는 캐리 비트를 최하위 비트에 더해주는 방식으로 계산한다.
1의 보수 연산 예시
캐리 비트가 발생하지 않는 경우
5 + (-5)- 이진수로 표현:
0101+1010 - 덧셈 결과:
1111 - 결과:
-0
- 이진수로 표현:
1 + (-5)- 이진수로 표현:
0001+1010 - 덧셈 결과:
1011 - 결과:
-4
- 이진수로 표현:
2 + (-3)- 이진수로 표현:
0010+1100 - 덧셈 결과:
1110 - 결과:
-1
- 이진수로 표현:
캐리 비트가 발생하는 경우
5 + (-3)- 이진수로 표현:
0101+1100 - 덧셈 결과:
1 0001(5비트, 캐리 발생) - 최상위 비트의 캐리
1을 최하위 비트에 더함:0001 + 0001=0010 - 결과:
2
- 이진수로 표현:
7 + (-4)- 이진수로 표현:
0111+1011 - 덧셈 결과:
1 0010(5비트, 캐리 발생) - 최상위 비트의 캐리
1을 최하위 비트에 더함:0010 + 0001=0011 - 결과:
3
- 이진수로 표현:
1의 보수 방식에도 몇 가지 문제가 남아 있다.
+0과-0이 존재하여0을 표현하는 방법이 두 가지이다 (0000,1111).- 연산 시 캐리 비트를 최하위 비트에 더해주는 추가 연산이 필요하다.
음수를 표현하는 방법 (3): 2의 보수(2’s Complement)
2의 보수(2’s Complement)는 이진수에서 음수를 표현하는 가장 일반적인 방법이며, 현대 컴퓨터 시스템에서 표준으로 사용된다. 산술 연산을 단순화하고 효율성을 높이기 위해 도입되었다.
2의 보수는 1의 보수에 1을 더하여 얻을 수 있다.
- 양수는 기존과 동일하게 표현한다.
- 음수는 해당 숫자의 이진수를 비트 반전한 후
1을 더하여 나타낸다.
4비트의 숫자를 2의 보수로 표현하면 다음과 같다.
| 10진수 | 2진수 |
|---|---|
| +7 | 0111 |
| +6 | 0110 |
| +5 | 0101 |
| +4 | 0100 |
| +3 | 0011 |
| +2 | 0010 |
| +1 | 0001 |
| +0 | 0000 |
| -1 | 1111 |
| -2 | 1110 |
| -3 | 1101 |
| -4 | 1100 |
| -5 | 1011 |
| -6 | 1010 |
| -7 | 1001 |
| -8 | 1000 |
2의 보수 방식을 사용하면 0의 표현이 유일해지고, 덧셈과 뺄셈을 동일한 방식으로 처리할 수 있다. 덧셈 연산만으로 뺄셈을 수행할 수 있으며, 최상위 비트에서 발생하는 캐리는 버린다.
원리 이해
이 방식은 일상생활에서도 사용할 수가 있다.
대표적으로 시계를 예로 들 수 있다.
시계는 24시간을 표현해주는 전자 시계가 있다고 가정해보자. 이 시계는 0시부터 23시까지 표현할 수 있다.
시계가 나타내는 시간이 5시 일 때, 이 시계를 2시로 바꾸고 싶다면 두 가지 방법이 있다.
- 시계 반대방향으로 3시간 이동
- 시계 정방향으로 21시간 이동
2의 보수 연산 예시
5 + (-5)- 이진수로 표현:
0101+1011 - 덧셈 결과:
1 0000(5비트, 캐리 발생) - 최상위 비트의 캐리
1은 버린다. - 결과:
0000(0)
- 이진수로 표현:
1 + (-5)- 이진수로 표현:
0001+1011 - 덧셈 결과:
1100 - 결과:
-4
- 이진수로 표현:
2 + (-3)- 이진수로 표현:
0010+1101 - 덧셈 결과:
1111 - 결과:
-1
- 이진수로 표현:
5 + (-3)- 이진수로 표현:
0101+1101 - 덧셈 결과:
1 0010(5비트, 캐리 발생) - 최상위 비트의 캐리
1은 버린다. - 결과:
0010(2)
- 이진수로 표현:
7 + (-4)- 이진수로 표현:
0111+1100 - 덧셈 결과:
1 0011(5비트, 캐리 발생) - 최상위 비트의 캐리
1은 버린다. - 결과:
0011(3)
- 이진수로 표현:
2의 보수 방식은 다음과 같은 장점을 가지고 있다.
0의 표현이 유일하여 혼란을 방지할 수 있다.- 양수와 음수를 동일한 회로로 처리할 수 있어 추가적인 캐리 처리가 필요 없으며, 효율적이고 빠른 연산이 가능한다.
오버플로우(Overflow)
정수 표현 시 2의 보수 방식을 사용하면 오버플로우(Overflow)에 대해 이해해야 한다. 2의 보수 방식에서는 n비트의 정수형이 표현할 수 있는 범위는 \(-2^{n-1} \sim 2^{n-1}-1\) 이 된다.
| 비트 수 | 표현 범위 |
|---|---|
| 4비트 | -8 ~ 7 |
| 8비트 | -128 ~ 127 |
| 16비트 | -32,768 ~ 32,767 |
| 32비트 | -2,147,483,648 ~ 2,147,483,647 |
오버플로우는 연산 결과가 표현 가능한 범위를 넘어설 때 발생하는 현상이다. 컴퓨터는 고정된 비트 수로 숫자를 표현하기 때문에, 범위를 벗어나는 값은 정확하게 표현할 수 없다.
예를 들어, 부호가 있는 4비트 정수형의 최대값은 7이다. 7 + 2를 계산하면 실제 결과는 9여야 하지만, 4비트로는 9를 표현할 수 없다.
- 이진수로 표현:
0111(7) +0010(2) - 덧셈 결과:
1001 - 결과는
-7로 해석되며, 이는 오버플로우가 발생한 것이다.
오버플로우는 부호 비트에서의 캐리 인(carry-in)과 캐리 아웃(carry-out)이 서로 다를 때 발생한다.
- 두 양수를 더했는데 결과가 음수가 나오는 경우
- 두 음수를 더했는데 결과가 양수가 나오는 경우
이러한 경우, 연산 결과가 실제로 기대하는 값과 다르게 나타나기 때문에 추가적인 오버플로우 검출 로직이 필요하다.
따라서 두 양수의 덧셈 결과가 음수로 나오거나 두 음수의 덧셈 결과가 양수로 나온다면 오버플로우가 발생했음을 알 수 있다. 이때는 자료형의 크기를 키우거나 오버플로우를 방지하는 방법을 찾아야 한다.