Last update: @12/1/2022
컴퓨터의 음수 표현
•
부호-크기 표현(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의 보수가 됨(two’s complement)
•
보수로 어떻게 뺄셈을 한다는 것일까? 원래 뺄 수를 취소 하고 오히려 그 수의 보수를 더한다는 개념으로 접근하면 직관적으로 이해할 수 있음
•
우리에게 익숙한 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을 날려주면 정답 4가 됨
▪
위에서는 보수의 기준값을 10으로 잡았지만 기준값을 100, 1000, … 등으로 정해서 2의 보수를 98, 998, … 등으로 놓아도 원리는 같음. 결과물만 104, 1004, … 등으로 변할 뿐, 맨 앞의 1을 날려주면 정답인 4가 그대로 남게됨
◦
정답이 음수인 경우: 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)가 됨. 따라서 결괏값 6의 보수인 4를 구해서 부호를 바꿔주면 원래 정답을 구할 수 있음
▪
하지만 정답이 양수/음수인 조건에 따라 추가적인 작업이 필요해보이는 건 아직 뭔가 불편한 구석이 있음
•
그렇다면 이렇게 정답이 양수일 때 맨 앞자리 수가 버려지거나, 정답이 음수일 때 결괏값의 보수를 구하는 것이 어떻게 처리된다는 걸까? 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)을 만든 후 0b1을 더하면 0b1111
▪
여러 포스트에서 -8이라는 수를 하나 더 표현하기 위해 첫번째 비트가 1인 음수에 대해 1씩 더해줬다는 설명을 보았는데, 불필요한 개념이 하나 더 끼어들어가서 ‘어떻게 별개의 개념들이 맞아 떨어져서 보수로 뺄셈을 하는거지?’라는 혼동만 주는 설명이라고 생각함. 첫번째 비트가 부호비트라는 개념을 버리고 단순히 2의 보수를 구했다고 생각하면 됨
◦
0b0111(7)에서 0b0011(3)을 빼는 경우
→ 나와야 할 정답 0b0100(4)
***
0b10000(16)을 기준으로 한 이진수 0b0010(2)에 대한 2의 보수는 0b1110(14)임. 보수라는 것은 자릿수를 기준으로 하기 때문에 같은 수에 대한 보수도 진법마다 다름. 따라서 십진수로 변환해서 생각하면 헷갈릴 수 있음
***
0 111
+1 101 (0010의 보수)
------
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의 보수는 존 폰 노이만이 제안한 방식임