0과1로 이루어진 컴퓨터 세계에 마이너스(-) 부호가 있을 리 없다.
그렇다면 컴퓨터는 뺄셈을 어떻게 실행할까? 또, 음수는 어떻게 표현할까?
바로 👉🏻보수를 이용한다.
보수 구하기
먼저 보수가 무엇인지 알아보자.
보수의 세계엔 두가지 보수가 있다.
n의 보수
와,n-1의 보수
가 그것이다.
2진수라면 2의 보수, 1의 보수가 존재하며
10진수라면 10의 보수, 9의 보수가 존재한다는 이야기다.
1. n-1의 보수
먼저, n-1의 보수
는 해당 수를 뒤집은 수다.
🤷♀️ 뒤집는 게 뭘까?
주사위를 생각하면 쉬울 것이다.
1눈의 반대편엔 항상 6, 2의 반대편엔 5, 3의 반대편엔 4가 있다.
주사위의 숫자들이 8진법의 세계 안에 있다고 한다면 반대편의 눈이 각각 7의 보수
가 되는 셈이다.
(적고 보니 주사위엔 눈이 6까지 밖에 없어서 약간 헷갈릴 수도 있겠다,,)
💁♀️ 2진수의 경우
2진법엔 0과 1뿐이므로 뒤집는다(toggle)는 개념이 쉽게 적용된다.
0을 뒤집으면 1, 1을 뒤집으면 0이다.
따라서 1101의 1의 보수
는 0010이 되며, 11111의 것은 00000이다.
💁♀️ 10진수의 경우
1을 뒤집으면 8, 2를 뒤집으면 7, 3은 6, 4는 5...9는 0이다.
따라서 99의 9의 보수
는 0이 되며, 45는 54, 38은 61이 된다.
다르게 말하면, n-1의 보수
란 더했을 때 자릿수가 올라가게 하는 수에서 1을 뺀 값이다.
99에 1을 더하면 100이 되어 자릿수가 올라가며 1에서 1을 뺀 0이 n-1의 보수
가 되는 것이다.
왜 이런 설명을 덧붙였는지는 n의 보수
를 읽어 보면 안다.
2. n의 보수
n의 보수
가 바로 더했을 때 자릿수가 올라가게 하는 수다.
즉, n-1의 보수
에서 1을 더한 값이다.
💁♀️ 10진수의 경우
10진법 계산이 우리에게 더 익숙하므로 자릿수가 올라가는 계산을 쉽게할 수 있다.
예컨대 45에 더했을 때 100이 되게하는 수를 찾으면 곧 10의 보수
가 되며
55가 45의 10의 보수
임을 알 수 있다.
💁♀️ 2진수의 경우
1101의 2의 보수
를 구하려면 다음과 같은 과정을 따른다.
- 수를 뒤집는다: 1101 -> 0010
- 뒤집은 수에 1을 더한다: 0010 + 1 = 0011
그리고 1101에 0011을 더하면,
1101
+ 0011
------
10000
이와 같이 5자리수가 되는 것을 확인할 수 있다.
보수로 뺄셈하기
그렇다면 보수를 이용한 뺄셈은 어떻게 하는 것일까?
1. 결괏값이 양수가 나올 때
나오는 결과값이 양수라면 아주 간단하다.
빼려는 수 혹은 더하려는 음수의 부호를 뺀 값을 n의 보수
로 바꾼 뒤 더해준다.
그리고 원래 수의 최대 자릿수를 넘어간 가장 큰 자릿수를 버리면 계산이 완성된다.
💁♀️ 10진수의 경우
먼저 10진수로 살펴보겠다.
54 - 34를 보수 뺄셈으로 계산한다고 하면 과정은 다음과 같다.
- 34를
10의 보수
로 변환: 100 - 34 = 66 - 변환한 수를 더한다: 54 + 66 = 120
- 초과한 자릿수를 버린다: 120 -> 20
54 - 34의 계산 값과 같다!
💁♀️ 2진수의 경우
그다음은 1101 - 0111을 보수 뺄셈으로 계산하는 과정이다.
(0111에 0을 쓴 이유는 뒤집기 편하게 자릿수를 가시화한 것이다.)
-
0111을
2의 보수
로 변환:- 0111 -> 1000 (먼저
1의 보수
로 변환) - 1000 + 1 = 1001 (1을 더하여
2의 보수
로 변환)
- 0111 -> 1000 (먼저
-
변환한 수를 더한다
1101 + 1001 ------ 10110
-
초과한 자릿수를 버린다: 10110 -> 0110
1101 (13) - 0111 (7) = 0110 (6) 이므로 계산 값이 같다!
2. 결괏값이 음수가 나올 때
나오는 결괏값이 음수라면 결괏값을 통해 부호 판단을 해주어야 한다.
컴퓨터는 마이너스를 말할 수 없기 때문에 판단은 우리의 몫이다.
💁♀️ 10진수의 경우
이번에도 먼저 10진수로 살펴보겠다.
34 - 54를 보수 뺄셈으로 계산한다고 하면 과정은 다음과 같다.
- 54를
10의 보수
로 변환: 100 - 54 = 46 - 변환한 수를 더한다: 34 + 46 = 80
이때, 나온 수가 100을 넘지 않는다는 사실을 알 수 있다.
10진수 보수 뺄셈에서 자릿수가 넘어간다(carry 발생)는 사실은 곧 결괏값이 양수임을 의미한다.
따라서, 앞서 구한 120의 경우 무시한 3자릿수의 1이 곧 + 부호 역할을 하는 셈이며,
54 - 34를 보수 뺄셈으로 계산한다고 하면 과정은 다음과 같다.
- 34를
10의 보수
로 변환: 100 - 34 = 66- 변환한 수를 더한다: 54 + 66 = 120
- 초과한 자릿수를 버린다: 120 -> 20
여기서의 80은 자릿수 넘김 없이 80이므로, 앞에 붙은 보이지 않는 0이 곧 - 부호다.
하지만, 우리가 원하는 결괏값은 -20인데 80은 뭘까?
보수 뺄셈에서 음수 부호가 붙은 값은 n의 보수
처리를 거쳐야 우리가 보기에 타당한 결괏값이 된다.
- 결괏값을
10의 보수
로 바꾼다: 100 - 80 = 20
따라서, 보이지 않는 0을 - 부호로 생각하고 보수화한 결괏값을 붙이면
34 - 54 = -20의 결괏값과 같다!
💁♀️ 2진수의 경우
2진수의 경우도 계산을 진행하며 설명하겠다.
0111 - 1101을 보수 뺄셈으로 계산한다면 과정은 다음과 같다.
-
-1101을
2의 보수
로 변환:- 1101 -> 0010 (먼저
1의 보수
로 변환) - 0010 + 1 = 0011 (1을 더하여
2의 보수
로 변환)
- 1101 -> 0010 (먼저
-
변환한 수를 더한다
0111 + 0011 ------ 1010
결괏값이 4자리로, 자리올림이 발생하지 않았다는 것을 알 수 있다.
따라서 자릿수를 버리지 않아도 되며, 이때 맨 앞의 자릿수는 결괏값의 부호가 된다.
1일땐 음수이며 0일땐 양수라는 의미이다.
결괏값이 양수가 나온 앞선 계산에서 보면
초과한 자릿수를 버린 다음 자릿수가 0임을 알 수 있다. 즉, 양수라는 의미!
0111을
2의 보수
로 변환:
- 0111 -> 1000 (먼저
1의 보수
로 변환)- 1000 + 1 = 1001 (1을 더하여
2의 보수
로 변환)변환한 수를 더한다
1101 + 1001 ------ 10110
초과한 자릿수를 버린다: 10110 -> 0110
- 부호를 제외한 수를
2의 보수
로 바꾼다:- 010 -> 101 (
1의 보수
로 바꿈) - 101 + 1 -> 110 (1을 더해
2의 보수
로 바꿈)
- 010 -> 101 (
0111 (7) - 1101 (13) = -110 (-6)으로, 결괏값과 일치함을 알 수 있다.
정리하자면,
보수를 더했을 때 자리올림이 발생하지 않는 경우, 결괏값은 무조건 음수다.
따라서 2진수라면 부호인 맨 앞자리를 무시하고 n의 보수로 변환하면 결괏값이 되는 것이다.
'Learnings > Computer Science' 카테고리의 다른 글
네트워크 통신 스토리텔링💁♀️ - 서버/클라이언트, IP, TCP, UDP 쉬운 설명 (5) | 2021.02.03 |
---|---|
유닉스와 리눅스 (2) | 2021.01.08 |
댓글