Skip to content

Posts 2의 보수법으로 음수 표현하기 #
Find similar titles

부호있는 정수를 표현하기 위해 사용하는 2의 보수법이 얼마나 자연스럽고 아름다운지 써보려고 한다. 초딩때 프로그래밍을 처음 배울때는 그냥 외웠었는데 중딩때 쯤 이게 얼마나 아름다운 방법인지에 깨달음(ㅎㅎ)이 왔었더랬다.

2의 보수법으로 음수를 표현하는 기계적 방법(즉 알고리즘)은 아래와 같다:

  1. 모든 비트를 뒤집는다. 예를 들어 양수가 00100000 였다면 11011111 (1의 보수)
  2. 여기에 1을 더한다. 예를 들어 11011111였다면 11100000

00100000(32)을 2의 보수법에 따라 음수로 인코딩한 값은 11100000(-32)이다.

대체 왜 이딴 짓을 하는걸까? 이게 뭐가 아름답나?

위의 절차를 잠깐 잊고 다른 방식으로 생각해보자.

정수의 수직선 #

초딩때 배운 수직선(perpendicular 말고 number line) 개념을 생각해보자. 선분 위에 자연수들이 늘어져있는거. 자연수가 아니라 정수를 나타내려면 0을 가운데에 그리고 왼쪽으로 음수가 나열되고, 오른쪽으로 양수가 나열되는 무한하게 긴 직선(양쪽에 화살표를 그려서 표현한다)을 그렸더랬다.

Number line

그런데 컴퓨터는 튜링 머신이 아니라서 메모리가 유한하기 때문에 무한하게 긴 직선 따위는 존재할 수 없다. 즉, 직선의 양 끝을 대충 잘라야 한다. 8비트 정수라면 -128에서 127 지점을 자르고, 16비트 정수라면 -32768에서 32767 지점을 자른다.

인코딩 #

직선의 양끝을 위와 같이 자른 다음에 직선의 양끝(-128과 127)을 이어붙여서 고리(ring)로 만들자:

Ring

(출처)

이 그림을 보고 0에서 시작해서 시계방향으로 돌면서 이진수 값을 하나씩 매핑하면 2의 보수법을 따르는 인코딩이 완성된다.

이 그림을 떠올리면 127 다음에 -128이 나오는 이유, 0은 00000000인데 -1은 11111111인 이유, 2의 보수법 인코딩에서 사칙연산이 자연스럽게 수행되는 이유, carry flag가 어떤 경우에 켜지며 그 때의 값이 어떻게 되는지 등 온갖 것들이 자연스럽게 이해된다.

참말 아름답지 아니한가?

Other Posts #

0.0.1_20140628_0