Please enable JavaScript to view the comments powered by Disqus.
Search
moon
sun
💹

2의 보수란 무엇인가? 왜 컴퓨터는 2의 보수를 사용할까? what is two’s complements

태그
bit
Algorithm
two complements
Math
공개여부
작성일자
2022/11/02
요즘 Bit 연산의 매력에 빠져들었는데 이 기회에 2의 보수가 뭔지 왜 필요하게 된 것인지 한번 정리해보려고 한다. 2의 보수를 알려면 1의 보수부터 정리해야 한다.
그 전에 우리끼리 한가지 함수를 만들었으면 한다.
fun inverse(number: Int): Int
Kotlin
복사
이 함수는 어떠한 숫자를 받으면 2진수로 반전 시킨다고 가정하자. 내부 구현은 논의하지 않겠다.
예를들어 1101 이 입력되면 출력은 0010 으로 반환된다.

보수

사전적 정의는 네이버 국어사전에서 가져왔다.
수학 각 자리의 숫자의 합이 어느 일정한 수가 되게 하는 수. 예를 들어 10의 7에 대한 보수는 3이다.

1의 보수

•
1의 보수는 위의 정의로 파악하면 다소 어렵다.
•
일단 비트를 반전 시킨다고 이해하면 좋다.
•
임의의 숫자 n 이 있을때 1의 보수는 위에서 정의한 함수 inverse(n) 의 결과가 1의 보수이다.

2의 보수

•
1의 보수에 + 1을 더하면 나온값이다.

왜 컴퓨터는 2의 보수를 사용할까?

개념 설명

000001012=5100001012=−5\begin{aligned} 00000101_{2} &= 5\\ 10000101_{2} &= -5 \end{aligned}
•
컴퓨터에서 2진수는 00000101 은 십진수로 5 이다.
•
컴퓨터에서 -5는 10000101 로 앞에 1을 붙이면 -5가 된다.
◦
가장 첫 번째 자리를 sign bit 라 한다.
•
8자리를 사용하니 8 bit 숫자이다.

1의 보수

1의 보수는 다음과 같다. 편리한 설명을 위해 4bit로 작성한다.
10002=−710012=−610102=−510112=−411002=−311012=−211102=−111112=−000002=000012=100102=200112=301002=401012=501102=601112=7\begin{align} 1000_2 &= -7 \\ 1001_2 & = -6 \\ 1010_2 &= -5 \\ 1011_2 & = -4 \\ 1100_2 &= -3 \\ 1101_2 &= -2 \\ 1110_2 & = -1 \\ 1111_2 &= -0 \\ 0000_{2} &= 0 \\ 0001_2 &= 1 \\ 0010_2 &= 2 \\ 0011_2 & = 3\\ 0100_2 & = 4\\ 0101_2 &= 5 \\ 0110_2 &= 6 \\ 0111_2 &= 7 \end{align}
1.
-1 은 inverse(1) 이다.
2.
-0 이 존재한다.

5+(−5)5 + (-5) 의 결과는 어떻게 될까?

0101+10101111\begin{aligned} &0101 \\ +&1010 \\ \hline \\ & 1111 \end{aligned}
5+(−5)−0\begin{aligned} &5 \\ +(-&5)\\ \hline -&0 \end{aligned}
111121111_2 이고 이 값은 −0-0 이다.

5+(−2)5 + (-2) 의 결과는 어떻게 될까?

0101+1101(1)0010\begin{aligned} &0101 \\ +& 1101 \\ \hline (1)&0010 \end{aligned}
1이 carriage bit 가 되어 5bit 값이 나온다.
하지만, 4bit 만 연산하기로 했기 때문에 앞의 1은 제외한다.
5+(−2)2\begin{aligned} &5 \\ +(-&2)\\ \hline &2 \end{aligned}
2진수 연산을 그대로 10진수로 옮기면 위와 같다.
실제로 5-2 는 3이지만, 1의 보수로 연산하면 2이다.

5+(−3)5+(-3)의 결과는 어떻게 될까?

0101+1100(1)0001\begin{aligned} &0101 \\ +& 1100 \\ \hline (1)&0001 \end{aligned}
5+(−3)1\begin{aligned} &5 \\ +(-&3)\\ \hline &1 \end{aligned}
동일하게 carriage bit 이 존재하지만 4bit 이므로 무시한다.
000120001_2 는 1의 보수에서 십진수로 1을 의미한다. 실제로는 2 이지만

1의 보수의 연산

•
5 + (-5) = -0
•
5 + (-2) = 2
•
5 + (-3) = 1
각각 1을 더하면 -0 을 제외하고는 실제 10진수의 연산 결과와 같다.
•
5 + (-5) = -0 + 1 = 1 (very close, not same)
•
5 + (-2) = 2 + 1 = 3 (same)
•
5 + (-3) = 1 + 1 = 2 (same)

2의 보수

10002=−810012=−710102=−610112=−511002=−411012=−311102=−211112=−100002=000012=100102=200112=301002=401012=501102=601112=7\begin{aligned} 1000_2 &= -8 \\ 1001_2 & = -7 \\ 1010_2 &= -6 \\ 1011_2 & = -5 \\ 1100_2 &= -4 \\ 1101_2 &= -3 \\ 1110_2 & = -2 \\ 1111_2 &= -1 \\ 0000_{2} &= 0 \\ 0001_2 &= 1 \\ 0010_2 &= 2 \\ 0011_2 & = 3\\ 0100_2 & = 4\\ 0101_2 &= 5 \\ 0110_2 &= 6 \\ 0111_2 &= 7 \end{aligned}
1.
-0은 존재하지 않는다.
2.
1의 보수 + 1

5+(−5)5 + (-5) 의 결과는 어떻게 될까?

0101+10110000\begin{aligned} &0101 \\ +&1011 \\ \hline \\ & 0000 \end{aligned}
5+(−5)0\begin{aligned} &5 \\ +(-&5)\\ \hline &0 \end{aligned}
이진수로 000020000_2 이고 이 10진수 값은 00 이다.

5+(−2)5 + (-2) 의 결과는 어떻게 될까?

0101+1110(1)0011\begin{aligned} &0101 \\ +& 1110 \\ \hline (1)&0011 \end{aligned}
1이 carriage bit 가 되어 5bit 값이 나온다.
하지만, 4bit 만 연산하기로 했기 때문에 앞의 1은 제외한다.
001120011_2 는 10진수로 3이다.
5+(−2)3\begin{aligned} &5 \\ +(-&2)\\ \hline &3 \end{aligned}
5-3 은 의심의 여지없이 3이다.

5+(−3)5+(-3)의 결과는 어떻게 될까?

0101+1101(1)0010\begin{aligned} &0101 \\ +& 1101 \\ \hline (1)&0010 \end{aligned}
1이 carriage bit 가 되어 5bit 값이 나온다.
하지만, 4bit 만 연산하기로 했기 때문에 앞의 1은 제외한다.
001020010_2 는 십진수로 계산하면 2 이다.
5+(−3)2\begin{aligned} &5 \\ +(-&3)\\ \hline &2 \end{aligned}
5-3은 2이다.
이렇게 계산해보면 오차 없이 가장 정확한 연산이 2의 보수가 된다. 따라서 컴퓨터는 양수, 음수의 연산의 오차를 제거하기 위해 2의 보수를 사용하는 것이 더욱 타당해진다.
함께 읽어보면 좋은 글