2006년 6월 26일 월요일

C#의 음수 이야기

255

위 값은 C#에서 sbyte 형이 가질 수 있는 최대 값입니다. 이 값을 16진수와 2진수로 각각 변환하면 다음과 같지요. (한번 직접 계산해보세요^^)

16진수 : 7    F  
2진수  : 0111 1111

2진수를 한번 봅시다. 첫 번째 자리가 0입니다. 왜 첫 번째 비트가 0으로 비어있을까요? 그 비트를 사용한다면 더 큰 수를 담을 수 있을텐데 말이죠. 이 의문을 품고 다음 수를 16진수와 2진수로 바꿔 봅시다.

-1

16진수 : - 0    1  
2진수  : - 0000 0001

간단하네요. ^^ 그런데 이 값을 컴퓨터가 이해하게 하려면 어떻게 하죠? 컴퓨터가 '-' 기호를 이해할 수는 없습니다. 여러분도 잘 알고 있지만 컴퓨터는 0과 1만을 인식할 수 있을 뿐이죠.

컴퓨터 과학자들은 이 문제를 해결하기 위해 부호 비트(Sign Bit)라는 방법을 도입했습니다. 아까 255를 2진수로 변환한 값의 첫 번째 비트가 비어 있는 것을 봤죠? 그 첫 번째 비트가 바로 부호 비트로 사용되는 것입니다.

예를 들어 부호 비트가 1이면 음수, 0이면 양수가 되는 것이죠. 1000 0001 은 -1, 0000 0001은 +1입니다. 오, 훌륭하지 않나요? 이제 아름다운 음수를 비트 조합으로 표현할 수 있게 됐습니다. 그러나 여기에도 한가지 문제점이 존재합니다. 1000 0000 ( -0)과 0000 0000( +0)이 같이 존재한다는 것입니다.

음수를 표현하기 위해 제시된 또 하나의 방법은 1의 보수라는 방법입니다. 비트를 반전시켜 부호를 바꾸는 방식인데, 이 경우에도 -0, +0이 존재하는 문제는 마찬가지로 존재합니다. 앞의 방식보다 좋은 점이라면 0과 1의 비트를 뒤집는 연산은 엄청 빠르기 때문에 음수를 빨리 계산해 낼 수 있다는 것이죠.

컴퓨터 과학자들은 1의 보수가 가지는 단점을 보완하는 2의 보수라는 방법을 고안해 냈습니다. 비트를 반전시킨 다음 1을 더하는 것인데, 이렇게 하면 +와 -의 두가지 0이 존재하는 문제를 제거할 수 있습니다. -1을 2의 보수로 표현하면 다음과 같습니다.

1) 0000 0001 // 1
2) 1111 1110 // 모든 비트 반전
3) 1111 1111 // 반전된 비트에 1을 더하여 -1 표현. 16진수로 표현하면 FF

마지막 3)의 1111 1111이 2의 보수로 표현한 -1인 것입니다. 현대의 모든 컴퓨터는 2의 보수 방식을 이용하여 음수를 표현합니다. 그럼 다음의 코드를 한번 컴파일해서 실행해 보세요.

코드 :

  using System;
 
  class MainApp
  {
       static void Main(string[] args)
       {
           sbyte a = -1;
           Console.WriteLine("{0}, {0:X2}", a);
       }
  }

결과 :

-1, FF

재미있죠? 더 재미있는 이야기를 계속해 보겠습니다. 부호 비트로 사용하는 첫 번째 비트를 사용하면 더 큰 값을 표현할 수 있겠죠? 다음 코드에서 a는 16진수로 표현하면 FF, 2진수로 표현하면 1111 1111입니다.

byte a = 255;

똑같은 1111 1111인데 byte형 변수에 담기면 255가 되고 sbyte형 변수에 담기면 -1이 됩니다. 장난 하나 쳐 봅시다. 1111 1111을 갖는 byte형 변수의 값을 sbyte로 형변환 해서 실제로 -1이 되는 지를 보는 겁니다. 다음 코드를 컴파일하여 실행해 보세요.

코드 :

  using System;
 
  class MainApp
  {
       static void Main(string[] args)
       {
           byte a = 255;
           Console.WriteLine("{0}, {0:X2}", a);

           sbyte b = (sbyte)a;
           Console.WriteLine("{0}, {0:X2}", b);           
       }
  }

결과 :

255, FF
-1, FF

위 코드와 결과를 통해 알 수 있듯이, 부호가 있는 자료형과 그렇지 않은 자료형 사이에 값을 교환하는 일에는 주의를 기울여야 합니다.

이렇게 해서 C#에서 음수를 표현하는 방식과 주의해야 할 점에 대해 알아봤습니다. 앞으로도 클릭하세요 C# 2.0 프로그래밍에서는 미처 다루지 못한 이야기들을 종종 나누고자 합니다. 자주 찾아와 주세요. (방명록이 그냥 방치되어 있습니다. 방명록도 자주 이용해 주세요.^^;)

댓글 없음:

댓글 쓰기