Created:
Last update:
컴퓨터의 음수 표현
컴퓨터에서 음수를 표현하는 대표적인 두 가지 방식이 있다.
부호-크기 표현(Signed-magnitude representation)
•
•
0과 1로 이루어진 컴퓨터에서 음수를 표현하기 위해서 맨 앞 비트(Most Significant Bit, MSB)를 부호 대신 사용하는 방법. 0이면 양수, 1이면 음수, 뒤의 숫자가 절댓값을 나타낸다.
•
이 방법은 알아보기도 쉽고 생성하기도 쉽지만 산술 연산이나 음수 비교 연산이 어려워진다.
◦
예를 들어 4비트 컴퓨터에서 10진법 계산 2 - 2를 위해 이진법 0010 + 1010을 계산하면 1100이 나오고 이는 -4라는 엉뚱한 숫자가 됨. 이를 해결하기 위해선 회로를 추가 구성해야 하는 등 쉽지 않은 일이다.
2의 보수(Two’s complement)
음의 정수를 표현하는 가장 보편적인 방식. 아래에 설명한다.
보수란?
보충하는 수를 의미한다.
N진법에 대해서 N-1의 보수
: 같은 자릿수에서 가장 큰 값이 되기 위해 필요한 수
ex> 10진수 33의 9의 보수(10-1의 보수): 두자리수에서 가장 큰 값 99가 되기 위해 99 - 33 = 66
N진법에 대해서 N의 보수
: 자릿수를 한 자리 늘리기 위해 필요한 가장 작은 수. N-1의 보수에 1을 더해주면 된다.
ex> 10진수 33의 10의 보수: 세자리수 100이 되기 위해 100 - 33 = 67
1의 보수(one’s complement)
•
위의 N-1의 보수에서 본 것처럼, 2진수에서 1의 보수(2-1의 보수)란 어떤 이진수의 자릿수를 유지한 채 가장 큰 수를 만들어주는 수를 말한다.. 가장 큰 수는 1로만 가득 찬 경우가 됨(10진법의 경우 9로만 가득 찬 경우)
◦
예를 들어 0010이 자릿수가 같은 가장 큰 수 1111이 되려면 1101을 더해줘야하는 것을 알 수 있음. 이 때 1101은 0010의 1의 보수가 된다.
▪
이 1101을 구하려면
•
0010의 1과 0을 반전시키거나
•
1111에서 0010을 빼는 두 가지 방법이 있다.
•
컴퓨터 입장에서는 단순히 모든 자리를 반전시키는 방법이 쉽고 빠르다.
•
1의 보수를 음수로 사용하는 컴퓨터는 매우 드물기 때문에 계산법은 몰라도 무방하다.
2의 보수(two’s complement)
•
위의 예제에서 본 것처럼 2의 보수와 1의 보수는 1만큼 차이가 남. 따라서 단순히 1의 보수에 1을 더해주면 2의 보수가 된다.
•
보수로 어떻게 뺄셈을 한다는 것일까? 원래 뺄 수를 취소 하고 오히려 빼려던 수의 보수를 더한다는 개념으로 접근하면 직관적으로 이해할 수 있다.
10진법 예시
우리에게 익숙한 10진법 예시로 개념을 잡아보자
•
결괏값이 양수인 경우: 7에서 3을 빼는 경우 → 4
7 - 3 = 4
위 식에서 3을 뺀 것을 취소하면
7 - 3 + 3 = 4 + 3
7 = 4 + 3 <- 정답에 3을 더한 효과
위 식에서 3에 대한 10의 보수인 7을 더하면
7 + 7 = 4 + (3 + 7) <- 정답에 10을 더한 효과
7 + 7 = 14
Plain Text
복사
◦
즉, 3을 빼는 대신 3에 대한 10의보수를 더한다는 말은 3을 빼는 것을 취소하고(+3), 3의 보수인 7을 더한다(+7)는 의미다. 즉, 그냥 10을 더해준다는 말이다. 따라서 이번 예제처럼 정답(4)이 양수인 경우, 최종 계산 결과물인 14에서 앞의 1을 날려주면(10을 빼주면) 정답 4가 된다.
◦
여기는 기존 값과 빼는 값 모두 한 자리수를 썼지만, 기존 값이 두자릿 수라면 100의 보수를 사용한 후 마지막에 100을 빼주면 된다.
•
결괏값이 음수인 경우: 2에서 6을 빼는 경우 → -4
2 - 6 = -4
위 식에서 6을 뺀 것을 취소하면
2 - 6 + 6 = -4 + 6
2 = -4 + 6 <- 정답에 6을 더한 효과
위 식에서 6에 대한 10의 보수인 4를 더하면
2 + 4 = -4 + (6 + 4) <- 정답에 10을 더한 효과
2 + 4 = 6
Plain Text
복사
◦
이렇게 결괏값(-4)이 음수인 경우, 빼야할 6을 취소하고 오히려 4를 더하면 원래 결괏값에 보수의 기준값인 10을 더한 결과와 같아진다.
◦
보수의 기준값인 10을 더했을 때 최종 계산 결괏값(6)이 원래 결괏값(-4)의 절댓값(4)의 보수(6)가 됨. 4의 보수를 -4로 취급하기로 했으므로, 4의 보수인 6은 -4와 같다.
2진법 예시
•
뺄셈의 결괏값이 양수일 때 맨 앞자리 수가 버려지는게 어떻게 처리된다는 걸까? 결괏값이 양수인지 음수인지를 따로 판별한다는 것인가?
◦
4비트 컴퓨터를 가정하고, 위 예시를 2진법으로 계산해보자
◦
먼저, 뒤의 3개 비트를 이용해 0부터 7까지 8개의 양수를 표현하고, 각 양수에 대한 음수는 2의 보수를 표현형으로 사용하기로 한다.
십진수 | 이진수 | 십진수 (표현형) | 이진수(표현형) | 십진수(실제) |
0 | 0 000 | |||
1 | 0 001 | -1 | 1 111 | 15 |
2 | 0 010 | -2 | 1 110 | 14 |
3 | 0 011 | -3 | 1 101 | 13 |
4 | 0 100 | -4 | 1 100 | 12 |
5 | 0 101 | -5 | 1 011 | 11 |
6 | 0 110 | -6 | 1 010 | 10 |
7 | 0 111 | -7 | 1 001 | 9 |
-8 | 1 000 | 8 |
◦
2의 보수를 구하는 법은 모든 자리를 반전시켜 1의 보수로 만들어준 후 1을 더해주면 쉽게 구해진다.
(이하, 이진법 앞에는 0b를 병기하고 이해를 돕기 위해 뒤 괄호 안에 십진법을 병기함)
▪
예를 들어 0b0001(1)을 반전시켜 0b1110(-2)을 만든 후 1을 더하면 0b1111
▪
다른 여러 블로그 포스트에서 -8이라는 수를 하나 더 표현하기 위해 0의 음수를 8로 정했다는 설명을 보았는데, 불필요한 개념이 하나 더 끼어들어가서 ‘어떻게 별개의 개념들이 맞아 떨어져서 보수로 뺄셈을 하는거지?’라는 혼동만 주는 설명이라고 생각한다. 첫번째 비트가 부호비트라는 개념을 버리고 단순히 2의 보수를 구했다고 생각하면 된다.
◦
0b0111(7)에서 0b0011(3)을 빼는 경우
→ 나와야 할 정답 0b0100(4)
***
0b10000(16)을 기준으로 한 이진수 0b0011(3)에 대한 2의 보수는 0b1101(13)이다. 보수라는 것은 자릿수를 기준으로 하기 때문에 같은 수에 대한 보수도 진법마다 다르다. 따라서 계산 중 십진수로 변환해서 생각하면 헷갈릴 수 있음을 주의해야 한다.
***
0 111
+1 101 (0011의 보수)
------
10 100 (맨 왼쪽 1은 범위를 벗어나 사라짐)
0 100 (결괏값)
Plain Text
복사
▪
0b0011(3)을 빼는 것을 취소하고 보수 0b1101(13)을 더해줬더니 원래 정답 0b0100에 0b10000(16)을 더한 것과 같은 0b10100이 결과로 나온다.
▪
4비트 컴퓨터이기 때문에 범위를 벗어난 첫번째 비트는 자동으로 사라지고 정답만 남음. 즉, 0b10000(16)을 빼준 셈이 되면서 맨 앞의 1이 날아간다.
◦
0b0010(2)에서 0b0110(6)을 빼는 경우
→ 현실 세계의 정답은 0b-0100(-4)이기 때문에 컴퓨터 내부의 정답은 0b0100(4)의 음수 표현인 0b1100이 나와야 한다.
0 010
+1 010 (0110의 보수)
------
1 100 (결괏값)
Plain Text
복사
▪
0b0110(6)을 빼는 걸 취소하고 오히려 2의 보수 0b1010(10)을 더해줬더니 원래 정답 0b-0100(-4)에 0b10000(16)을 더해준 것과 같은 효과가 난다.
▪
따라서 0b1010(4)의 보수인 0b1100이 결과로 나타남. 원래 정답 0b-0100(-4)의 절댓값인 4의 보수임. 애초에 음수는 양수의 2의 보수를 표현형으로 하기로 했으니 이 결괏값을 그대로 저장하면 된다.
기타
2의 보수는 존 폰 노이만이 제안한 방식이다.