N Log

보수

컴퓨터가 뺄셈을 어떻게 수행하고 음수를 표현하는지 이해하려면 보수(補數, complement)를 알아야 한다.
보수는 정해진 기준값에 도달하기 위해 보충해야 하는 수다.
먼저 익숙한 10진법에서 보수의 원리를 살펴보고, 이를 2진법의 2의 보수로 확장해 보자.

10진법에서의 보수

10의 보수

한 자리 수에서는 10이 되기 위해 보충해야 하는 수를 10의 보수라고 생각할 수 있다.

3의 10의 보수는 3이 10이 되도록 보충하는 수이므로 7이다.
같은 원리로 6의 10의 보수는 4다.

그렇다면 두 자리 수 12의 10의 보수는 무엇일까?
12는 이미 10보다 크므로, 앞의 설명만으로는 보수를 구할 수 없다.
10의 보수에서 10은 언제나 10 자체를 뜻하는 것이 아니다.
nn자리로 표현한 수 xx의 10의 보수는 xx에 더해 10n10^n을 만드는 수다.
따라서 다음과 같이 구한다.

10nx10^n - x

두 자리 수 12의 10의 보수는 10212=8810^2 - 12 = 88이다.
세 자리 수 123의 10의 보수는 103123=87710^3 - 123 = 877이다.

9의 보수

9의 보수는 각 자리 수가 9가 되기 위해 보충해야 하는 수를 의미한다.

3의 9의 보수는 6이다.
6의 9의 보수는 3이다.
12의 9의 보수는 87이다.
123의 9의 보수는 876이다.

10의 보수를 10nx10^n - x로 계산하면 뺄셈 과정에서 빌림이 발생해 불편하다.
xx에 보충할 수를 생각해 덧셈으로 구하려 해도 자리올림을 고려해야 해서 계산이 불편하다.
반면 9의 보수는 각 자리 숫자가 9가 되도록 보충하기만 하면 되므로 쉽게 구할 수 있다.

9의 보수와 10의 보수 사이에는 다음 관계가 있다.
9의 보수에 1을 더하면 10의 보수가 된다.
따라서 10의 보수를 구할 때는 먼저 9의 보수를 구한 뒤 1을 더하면 된다.
예를 들어 35의 9의 보수는 64이고, 여기에 1을 더하면 35의 10의 보수 65를 구할 수 있다.

10의 보수를 이용한 뺄셈

보수를 이용하면 덧셈으로 뺄셈 결과를 얻을 수 있다.

한 자리 수 939 - 3을 계산해 보자.
3을 빼는 대신 3의 10의 보수인 7을 더한다.
9+7=169 + 7 = 16이므로, 십의 자리 올림수 1을 버리면 6이 남는다.
이는 939 - 3의 결과와 같다.

3의 10의 보수는 10310 - 3이므로, 이 과정을 식으로 나타내면 다음과 같다.

93=93+1010(1)=9+(3)+1010(2)=9+((3)+10)10(3)=9+(103)10(4)=9+710(5)=6\begin{aligned} 9 - 3 &= 9 - 3 + 10 - 10 &&\text{(1)} \\ &= 9 + (-3) + 10 - 10 &&\text{(2)} \\ &= 9 + \bigl((-3) + 10\bigr) - 10 &&\text{(3)} \\ &= 9 + (10 - 3) - 10 &&\text{(4)} \\ &= 9 + 7 - 10 &&\text{(5)} \\ &= 6 \end{aligned}

(1)은 +1010+10 - 10처럼 같은 수를 더하고 빼도 식의 값이 변하지 않는다는 것을 이용한 것이다.
(2)는 뺄셈을 음수의 덧셈으로 바꾼 것이다.
(3)은 덧셈의 결합법칙을 이용해 3-31010을 묶은 것이다.
(4)는 덧셈의 교환법칙을 이용해 3+10-3 + 1010310 - 3으로 바꿔 3의 10의 보수를 만든 것이다.
(5)는 10310 - 3을 계산해 3의 10의 보수인 77로 바꾼 것이다.
(5)의 10-10은 자리올림을 버리는 것과 같다.

2진법에서의 보수

1의 보수

1의 보수는 각 비트를 1이 되게 만드는 수다.
4비트로 0101을 표현했다면 1의 보수는 1010이다.
이때 각 비트가 1이 되도록 더하는 수를 생각할 수도 있지만 더 쉬운 방법이 있다.
각 자리의 비트를 01로, 10로 반전시키면 된다.

2의 보수

곧바로 2의 보수를 구하는 것은 불편하다.
4비트 0101의 2의 보수는 더해서 0000이 되게 만드는 수인데, 이를 구하려면 자리올림까지 신경 써야 한다.

10진법에서 9의 보수에 1을 더해 10의 보수를 구했던 것과 같은 방법을 사용할 수 있다.
먼저 1의 보수를 구하고, 여기에 1을 더하면 2의 보수가 된다.

예를 들어 4비트 0101의 1의 보수는 1010이다.
10101을 더하면 1011이 되므로, 0101의 2의 보수는 1011이다.
실제로 01011011을 더하면 1 0000이 된다.
4비트 범위에서 맨 앞의 자리올림 1은 버려지고 0000만 남는다.

2의 보수를 이용한 뺄셈

10진법에서 뺄셈을 보수의 덧셈으로 바꿨듯, 2진법에서도 빼려는 수의 2의 보수를 더하면 된다.

4비트 범위에서 737 - 3, 즉 0111 - 0011을 계산해 보자.
0011을 빼는 대신, 그 2의 보수인 1101을 더하면 된다.

+0111(7)+1101(3)1 0100\begin{array}{rl} \phantom{+}\mathtt{0111} & (7) \\ +\mathtt{1101} & (-3) \\ \hline \mathtt{1\ 0100} & \end{array}

맨 앞의 자리올림 1을 버리면 2진수 0100이 남으며, 이는 10진수 44다.