2의 보수

지환·2022년 5월 29일
0

1학년 컴퓨터학개론 시간에 컴퓨터에선 음수를 2의 보수로 표현한다고 배웠었다.(정확히는, 음수를 해당 수의 절댓값의 2의 보수로 나타낸다.)
그렇게해야 빼기 연산이 더 자연스럽다고 교수님께서 말씀해주셨었는데, 슬슬 가물가물해져서 다시 머릿속에 있는걸 정리해볼까한다.


보수(Complement)

radix(기수)가 k일때 특정 수 a의 "보수"라함은, (쉽게 말해) a에 양수 b를 더했을때 k의 거듭제곱이 된다면 b를 a의 보수라고 한다.

이진수에서 보수를 어떻게 구할까?
간단하다. 비트를 모두 반전시키고, 1을 더하면 된다.
4비트 크기에서 1011(2)1011_{(2)}의 보수를 구하려면, 먼저 비트를 모두 반전시킨다, 0100(2)0100_{(2)}.
둘을 더하면 10000(2)10000_{(2)}이 나와야하는데 반전시킨 놈과 더하면 1111(2)1111_{(2)}이 나온다.
따라서 보수를 구할때 1을 마지막에 더해주는 것이다. (마찬가지로 10진수 기준 2의 보수는 7이 아니라 8이다.)
(비트 수 따라 다르게 구해질 수 있는데, 8비트 00001011(2)00001011_{(2)}의 2의 보수는 11110101(2)11110101_{(2)}이다.)

즉, 컴퓨터에서 (4비트 공간에서) 특정 수 A(2)=(10000(2)A(2))-A_{(2)} = (10000_{(2)}-A_{(2)}) 이다.
(풀어서 말하면, 보수 취해서 마이너스 붙이면 같은 수다. 마이너스가 붙거나, 최상위 bit가 1이거나로 음수를 표시)

2의 보수 빨리 읽기

"부호비트 자리의 값 - 나머지 비트 전부 더한 값"에 (minus)-(minus)기호를 붙이면 된다.

예를들어,
1101 = 8(부호비트 자리 값) - 5(0101 더한 값) = 3 이니, 저 2진수는 3-3을 나타낸다.

왜 그런가하면, 일단 MSB가 1인 숫자는 2의 보수로 나타나진 것이다.(이쪽에선 그렇게 나타내니까..)
즉, 저 숫자가 원래 뭐였는지(저 숫자의 2의 보수를 구하면 되겠지) 구해서 마이너스를 붙여주면 된다.
그런데 위처럼 해석한다는 것은 "부호비트 자리의 값 - 나머지 비트 전부 더한 값"이 결국 해당 숫자의 2의 보수란 소린데.. 원래 숫자와 우리가 저 수식을 이용해 구한 숫자를 더해서 2의 보수인지 확인해보자.
원래 숫자와 "부호비트 자리의 값 - 나머지 비트 전부 더한 값"를 더하면 당연히 뒤의 "나머지 비트 전부 더한 값"끼리는 날아가고, 부호비트끼리만 둘이 더해지니 10000(2)10000_{(2)} 꼴이 나온다.
즉, 2의 보수가 구해진다는 뜻이므로 거기에 마이너스만 붙여주면 된다.

보수를 이용한 계산

보수를 이용하면 뺄셈을 덧셈처럼 할 수 있다.

A(2)B(2)A_{(2)}-B_{(2)}를 구해보자.
A든 B든 가장 큰 자리수는 최대 4번째라고 가정하겠다.(4비트로 제한)

우선 B(2)B_{(2)}를 보수형태로 바꿔 덧셈으로 바꾼다.
A(2)+(10000(2)B(2))A_{(2)}+(10000_{(2)}-B_{(2)})
식을 좀만 바꾸면,
(A(2)B(2))+10000(2)(A_{(2)}-B_{(2)})+10000_{(2)}
즉, 음수를 2의 보수 형태로 바꿔서 더해버린 후 carry를 없애면 원하는 결과(A(2)B(2)A_{(2)}-B_{(2)})가 나온다는 것을 알 수 있다.

여기서 두가지 경우로 나뉘는데,
1) 저렇게 계산했을때 실제로 carry가 발생한다면?
: 그냥 carry를 없애버리면 된다.

2) 실제로 carry가 발생하지 않는다면?
: 얘도 마찬가지로 carry(10000(2)10000_{(2)})를 없애야하므로 결과에 10000(2)-10000_{(2)} 를 해야한다.
결과였던 (A(2)B(2))+10000(2)=C(2)(A_{(2)}-B_{(2)})+10000_{(2)} = C_{(2)}라고 해보자.
우리가 원하는 결과는 C(2)10000(2)C_{(2)}-10000_{(2)} 이다.
정리하면, 우리가 원하는 결과는 (10000(2)C(2))-(10000_{(2)}-C_{(2)}) 이다. (익숙한 표현법으로 보고싶으면 이렇게 C(2)C_{(2)}의 2의 보수 구해서 마이너스만 붙여주면 됨)
이는 음수이다. 컴퓨터는 음수를 어떻게 나타낸다고? 절댓값의 2의 보수로.
따라서 우리가 원하는 결과는 (위의 (10000(2)C(2))-(10000_{(2)}-C_{(2)})도 맞지만, 컴퓨터에선 음수를 2의 보수로 표현하니까) C(2)C_{(2)}이다.
즉, 실제로 carry가 발생하지 않는다면 추가로 할 게 없다.

정리
컴퓨터에서 뺄셈은, 음수의 절댓값의 2의 보수를 (특정 bit수에서) 구하고 둘을 더한다.
더해서 carry가 발생하면 버린다.
끝.

0개의 댓글