음수와 양수를 binary로 어떻게 표현되는가?

1 분 소요

intro.

  • 사실, 우리는 10진법의 세상에 살고 있지만, 컴퓨터는 2진법의 세상에 살고 있습니다. 물론, 우리가 변수를 선언 및 정의할 때 이진법을 사용하지는 않지만, 컴퓨터는 이진법으로 계산을 처리하죠.
  • 오늘 이야기할 부분은 몰라도 되지만, 재미삼아, 그리고 알게 되었으니 정리를 하기로 합니다.

첫번째 digit이 0이면 양수, 1이면 음수

  • 우선, integer를 bit로 저장할 때, 첫번째 bit는 음수인지 양수인지를 알려주는 역할을 가집니다. 첫번째가 0이면, 양수, 1이면 음수가 되죠. 그렇다면, 가령, 4bit에 3를 저장한다고 하면 값을 다음과 같이 표현되는 것이겠죠?
 3 => 0011
-3 => 1011
  • 실제로 그런지 한번 파악해봅시다. python에서 어떤 수의 binary 형태를 알고 싶다면, np.binary_repr를 사용해야 합니다.
from numpy import binary_repr

print(binary_repr(3, width=4))
print(binary_repr(-3, width=4))
  • 어? 좀 이상하죠? 우리가 앞에서 말한 것과 다른 형태로 표현이 되었네요.
0011
1101

왜 그럴까?

  • 우리는 어떤 수평선 상에서, 음수와 양수를 똑같이 이해하고 있습니다. 맨 앞만 0, 1로 양수/음수를 표기해주고 나머지 표현은 똑같을거라고, 이해하게 되죠. 하지만, 실제로는 그렇게 되지 않아요.
  • 처음에 우리가 생각한대로, 3, -3 을 bit로 표현한다고 생각하고 더해봅시다. 그러면, 1110 즉, -6이 나오게 되죠. 0이 나와야 하는데, 0이 나오는 것이 아니라, 오히려 음수를 두 배 한 값이 나온 것이죠.
   3 = 0011 
+ -3 = 1011
------
= 1110
  • 이를 방지하기 위해서, 다른 형태로 음수를 표현하게 됩니다. 그리고 우리는 현재 수를 4bit로만 표현한다고 할게요(맨 앞 bit는 0이면 양수, 1이면 음수입니다).

전개

  • x + (-x) = 0000이어야 합니다.
    • 여기서 0000은 0이거나, 1 0000 모두 가능합니다. bit 칸을 넘겨버리면 컴퓨터는 앞에를 날려버리거든요.
  • 따라서, x + (-x) = 1 0000이 됩니다.
  • 그리고, x + (-x) = 1111 + 0001이 됩니다.
  • 그리고, 여기서 보수(complement)라는 개념이 들어가는데, 보수는 원래 0인 것을 1로, 1인 것을 0으로 바꿔주는 것을 말합니다. 만약 1100의 보수라면 0011이 되는 것이죠.
  • 따라서, x + (-x) = x + complement(x) + 0001이 됩니다.
  • 그래서, (-x) = complement(x) + 0001이 됩니다.
  • 즉, -x는 x의 보수(complement)에 1을 더한 값이 되는 것이죠.

in python

  • 정말 그런지 보겠습니다.
from numpy import binary_repr

x = 3 
print(f" x  :  {x} => {binary_repr(x, width=4)}")
print(f"~x  : {~x} => {binary_repr(~x, width=4)}")
print(f"~x+1: {~x+1} => {binary_repr(~x+1, width=4)}")
print(f"-x  : {-x} => {binary_repr(-x, width=4)}")
 x  :  3 => 0011
~x  : -4 => 1100
~x+1: -3 => 1101
-x  : -3 => 1101

댓글남기기