메뉴
[Number Systems] Negative Numbers

2012. 2. 7. 20:56

시작하기 전에

Digital은 컴퓨팅이나 데이터 처리, 제어시스템, 통신, 측정 등에 널리 쓰이고 있다.
Analog에 비해서 정확하며 믿을만 하기 때문이다.
모든 수치들이 quantized, 즉 discrete한 값을 갖는다.
데이터의 수치를 어떤 하나의 voltage나 current level로 결정되는 것이 아니라
0과 1의 binary로 되어있는 숫자들의 묶음으로 되어있기 때문에,
(물론 0과 1이라는 것이 voltage나 current level과 완전히 동떨어져서 생각할 수 있는 것은 아니다.)
digital이 analog에 비해서 정확한 값을 얻을 수 있을 가능성이 훨씬 높다.
Digital이 근 10~20년 사이 급격히 각광받고 있는 이유가 여기에 있다.
물론 digital logic에 관한 이론도 같은 속도로 발전해 왔고, 우리는 digital에 대한 이해가 필요하게 되었다.

본격적인 digital logic circuit을 다루기 이전에
binary에 대한 내용에 대해서 살펴볼 필요가 있다.
기존의 10진수 또근 16진수 8진수 등등을 2진수로 변환하는 과정이라든지
2진수의 사칙연산은 여기서는 다루지 않는다.
다만 음수 표현법 정도는 다루고 넘어갈 필요성이 있다고 생각되어 여기서 짚고 넘어가도록 하겠다.




Representation of Negative Numbers

음수를 표현하는 방법으로 가장 많이 사용되는 것은 most significant bit (MSB)를 이용하는 방법이다.
예를 들어 100000000000000000000000000000 과 같은 2진수에서 '1'의 위치에 있는 bit를 말한다.
그 반대는 least significant bit (LSB)이다.

MSB를 'sign bit'로 만듬으로써 음수를 표현하게 되는데,
예를 들어 0인 경우에는 양수를, 1인 경우에는 음수를 표현한다고 정해두는 것이다.
이렇게 맨 앞의 bit를 sign bit로 미리 정해놓았다면,
이제는 나머지 뒤에 오는 숫자들을 어떻게 정할 것인가에 대한 문제가 남는다.
일반적으로 3가지 방법이 존재한다.  



Sign and Magnitude

그 첫번째 방법이 Sign and Magnitude다.
그다지 들어본 적이 없는 방법일 것이다. 사실 거의 쓰이지 않는 방법이기도 하다.
예를 들어서 0, 1, 2, 3, 4, 5, 6, 7 을 4bit의 2진수로 표현하면 각각
0000, 0001, 0010, 0011, 0100, 0101, 0110, 0111이 된다.

Sign and Magnitude는 그냥 이 상태에서 MSB를 1로 바꾼것에 불과하다.
다시 말해서 -0, -1, -2, -3, -4, -5, -6, -7이 곧
1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111로 변환된다.

이 방법이 잘 쓰이지 않는 이유는 연산에 있는데,
먼저 1과 -1을 그냥 직관적으로 더하면 1010이 된다. 이는 곧 -2가 된다.
우리가 원하는 값인 0과 전혀 동떨어진 값이 된다.
따라서 1과 -1을 더해서 우리가 원하는 값을 얻으려면 부가적인 체크 및 연산을 해줘야 한다.
이는 곧 더 많은 logic gate를 필요로 한다. 쉽게 이야기 하면 쓸데없는 게 많아지고 돈이 더 많이 든다.
인간이 이해하기도 힘들고 컴퓨터도 이해하기 힘들다.
그래서 여기서 한단계 발전한 것이 1's complement다.




1's complement

'1의 보수'라고 흔히 부르는 것이다. 방법은 간단하다. 
0, 1, 2, 3, 4, 5, 6, 7 을 4bit의 2진수로 표현하면 각각
0000, 0001, 0010, 0011, 0100, 0101, 0110, 0111이 되는데, 여기서 0은 1로, 1은 0으로 모조리 바꿔주는 것이다.

즉, -0, -1, -2, -3, -4, -5, -6, -7이 각각
1111, 1110, 1101, 1100, 1011, 1010, 1001, 1000이 되는 식이다.

이 경우에는 연산이 조금 더 그럴싸 하게 돌아간다.
5와 -6을 더하면, 0101 + 1001 = 1110 이 되고 이는 -1에 해당하는 숫자다. 곧바로 계산이 된다.
하지만 항상 이렇지는 않다. -3와 -4을 더하는 연산을 한다고 하면, 1100 + 1011 = 10111 이 나온다.
자리수를 초과하게 된다. 하지만 이 경우에, 앞에 튀어나온 1 (이것을 carry라고 한다.)을 없애면, 0111 이 되고
여기에 carry를 더하면 0111 + 1 = 1000 이 된다. 이는 곧 -7에 해당하는 값이다. 옳은 결과값이다.

하지만 1's complement 역시 단점이 있다.
일단 0과 -0은 논리적으로 유의미한 차이가 없다. 그런데 0은 두 가지의 표현 0000과 1111을 갖게 된다.
carry를 이용하는 방법으로 제한된 bit space 안에서 덧뺄셈 연산은 닫혀있긴 하지만, 
단순히 bit를 비교하는 방법을 사용해 어느 숫자가 큰가를 알아보는 장치를 만든다면 0000과 1111로 인해서
추가적인 장치들이 필요하게 된다. 마찬가지로 carry를 다시 가져와서 더해주는 것 역시 효율적이지 못하다.
게다가 16가지의 숫자를 나타낼 수 있는 4bit임에도 결론적으로는 15가지의 숫자 밖에 나타내지 못하고 있다.




2's complement

마찬가지로 '2의 보수'라고 부른다.
여기서는 양수를 1의 보수로 만든 다음 거기에 1을 더한 것이다. 
즉, -1, -2, -3, -4, -5, -6, -7, -8이 각각
1111, 1110, 1101, 1100, 1011, 1010, 1001, 1000이 되는 식이다. 

이전에 있던 -0이 없고 대신 -8이 생겼다. 4bit를 온전히 이용할 수 있다.
게다가 그냥 더하면 그게 곧 결과가 된다.
-3 더하기 -4 를 하면 11001이 나온다.
하지만 여기서는 carry를 다시 더할 필요가 없다. 그냥 버리면 그게 곧 -7이다.
연산 과정에 있어서 매우 간단하다. 
물론 이것 역시 negate (음수화) 과정에서 1을 더해야하는 수고가 필요한 단점이 있다.

Sign and Magnitude가 못마땅해서 1의 보수가 나오고 또 그게 못마땅해서 2의 보수가 나온 것인지는 모른다.
다만 이해하기 편하게 하기 위해서 이런 식으로 이야기를 펼쳐나갔을 뿐이므로 오해가 없길 바란다.
음수화 과정에 대해서는 여기서 더 특별히 다룰만한 것이 없는 것 같아 이만 줄인다.