세인드의 블로그


2진법만 사용하는 컴퓨터는 어떤 방식으로 음수를 표현할까?

컴퓨터는 오로지 전기신호인 1과 0, 즉 on과 off만을 인식하여 2진 연산을 합니다.
우리가 일상에서 사용하는 10이라는 수와 -10이라는 수, 즉 부호를 사용함에 따라서 음수와 양수를 나눌 수 있습니다.
그렇다면, 부호를 사용할 수 없는 컴퓨터는 어떤 방식으로 음수를 표현할까요?

부호 비트

8비트의 메모리 공간에 23이라는 수를 저장하려 한다고 가정한다면 메모리 공간에는 아래와 같은 수가 할당됩니다.

0  0  0  1     0  1  1  1    => 23

8비트의 메모리공간에 양수만을 저장한다면 0~255까지의 수를 표현할 수 있습니다.
하지만 음수를 표현하지 못한다는 문제가 생기기때문에 음수를 표현하기 위해서
최상위 비트, 즉 msb를 부호비트로 사용하게 됩니다.
msb가 0이라면양수를 의미하고, msb가 1이라면 음수를 의미합니다.

0  0  0  1     0  1  1  1    => 23
1  0  0  1     0  1  1  1    => -23

부호비트를 이용하여 음수값 -23을 표현해봤습니다.
하지만, 이와 같이 부호비트만을 이용하여 음수를 표현한다면 연산시에 큰 문제가 생기게 됩니다.
예를들어 23 + (-23)을 연산하게되면 0이라는 값을 반환해야 하지만 부호비트를 사용한 2진 연산시
46이라는 엉뚱한 값을 반환하게 됩니다.

0  0  0  1     0  1  1  1
1  0  0  1     0  1  1  1
1  0  1  0     1  1  1  0     => -46반환

이와같은 문제를 해결하기위해서 1의보수를 이용한 연산방법이 등장하게 됩니다.



1의 보수

1의 보수를 알아가기 전에 일단 "보수"라는것의 개념부터 생각해보도록 하겠습니다.
10진 정수를 예를들어 6이라는 수가 있다면 이를 10으로 만들기 위해서는 4라는 수를 보충해주어야 합니다.
즉, 10-6 = 4; 6에대한 10의 보수는 4가 되는거죠.

하지만 컴퓨터에서 사용하는 1의 보수의 개념은 약간 다릅니다.
컴퓨터에서 1의 보수는 1과 0을 반전시켜주는 역할을 합니다.

0  0  0  1     0  1  1  1  =>  23
1  1  1  0     1  0  0  0  =>  23에대한 1의 보수

1의 보수를 구했으니 연산을 해보겠습니다. ( 23+(-23) )

0  0  0  1     0  1  1  1  =>  23
1  1  1  0     1  0  0  0  =>  23에대한 1의 보수
1  1  1  1     1  1  1  1     => 256반환

23 + (-23)을 연산시 우리가 원하는 값은 0입니다. 하지만, 1 1 1 1  1 1 1 1이 결과로 반환되게 됩니다.
잠깐 여기에서 생각의 시간을 갖도록 합시다.
우리는 1의 보수를 배웠습니다. 결과값에 1의 보수를 취해주면??

1  1  1  1     1  1  1  1  
0  0  0  0     0  0  0  0  => 1의 보수

드디어 원하는 결과값인 0이 나왔습니다.
하지만 1의 보수만을 사용하여 연산을 할 시 비트 반전을 너무 많이 해야한다는 단점이 있습니다.
그래서 등장하게 된 것이 2의 보수입니다.

2의 보수

2의 보수는 1의 보수에 1을 더해주었을때의 결과값을 의미합니다.
위에서 구한 23에대한 1의 보수에 1을 더해보겠습니다.

1  1  1  0     1  0  0  0  =>  23에대한 1의 보수
1  1  1  0     1  0  0  
1  =>  2의 보수 (+1)

2의 보수까지 구했으니 연산을 해보겠습니다.

   0  0  0  1     0  1  1  1
   1  1  1  0     1  0  0  1
1  0  0  0  0     0  0  0  0     => 9비트로 반환 (
데이터 표현범위 초과; overflow )

처음에 8비트의 메모리 공간을 가정했기때문에 9비트로 반환된 값은 데이터 범위를 초과하게 됩니다.
따라서 초과한 1비트는 무시되고 최종으로 반환되는 값은 [ 0  0  0  0      0  0  0  0 ]이 됩니다.

이런 방식으로 컴퓨터는 부호 없이도 더하는 연산만을 이용하여 마이너스값을 표현합니다.
즉, 23에대한 2의 보수인 [ 1  1  1  0     1  0  0  1 ]이 -23을 의미하게 되는거죠.



2의 보수를 사용함으로써 생기는 효과

1의 보수를 구지 사용하지 않고 구지 2의 보수를 사용하여 연산을 하는 이유는 위에서 보신바와 같이 
쓸데없는 연산을 줄일 수 있기때문입니다.
예를들어 4비트의 데이터공간에서 1의 보수를 이용하여 마이너스연산을 한다면 8번의 비트반전이 수행됩니다.
만약 8비트의 데이터 공간을 가정한다면 16번의 비트반전이 이루어지겠죠.
즉, 1의 보수를 사용하여 연산을 한다면 2n번의 비트반전을 수행하게 됩니다.
요즘은 32비트를 넘어서 64비트까지 처리할 수 있는 능력을 가진 CPU가 출시되고 있는데 만약 이를 1의 보수로 연산한다면
굉장한 자원의 낭비가 이루어질 수 밖에 없겠죠..

하지만, 2의 보수를 사용한다면 4비트의 공간에선 4번의 비트반전과 +1의 연산을,
8비트에선 8번의 비트반전과 +1의 연산만이 필요하게 됩니다.
즉, 2의 보수를 사용한 연산은 n+1번의 비트반전이 이루어지게 됩니다.

여기까지 C언어가 어떻게 음수를 표현하는지에 대해서 알아보았습니다.
이와같은 방법은 C언어뿐 아니라 컴퓨터가 내부적으로 음수를 처리하는 방법과도 일치합니다.

'프로그래밍 > C' 카테고리의 다른 글

최상위 비트를 의미하는 MSB(Most Significant Bit)  (0) 2011.02.19
C언어의 역사  (0) 2011.02.12