본문 바로가기

PROGRAMMING/JAVA

잠깐) 보수법

최근 공부를 하다가 음수인 2진수를 10진수로 바꾸는 방법을 몰랐던 일이 있었다. 또잉~

그래서 보수법에 관해 질문을 하였고 가르침 받은 토대로 보수법에 관해 정리한 포스팅이다.


보수법(complement) 이란?

: 원래 컴퓨터 내부에서 음의 수가 양의 수와 마찬 가지로 계산될 수 있도록 표현하기 위해 고안된 1의 보수가 있었다. 하지만 0이 00000000과 10000000, 이렇게 두가지로 표현되는 문제가 나타났다. 

이를 보완하기 위해 1의 보수 후 1을 더해 완성하는 2의 보수법이 나왔고 현재는 1의 보수는 쓰이지 않는다.


컴퓨터는 '1+1 = 2' 라고 인식한다.

하지만 '3 - 2 = ' 을 인식하지 못한다. 왜냐하면 (-) 기호 연산자를 지원하지 않기 때문이다.

그렇다면 저 식을 어떻게 읽어 내는가?

'3 + (-2) = ' 로 인식하여 결과를 도출해내는 것이다.


이 때, 저 연산을 위해 양의 정수를 음의 정수로 변환하기 위해 보수법을 사용한다.


먼저 1의 보수부터 설명하겠다.

방법은 10진수를 2진수로 변환하고 0을 1로, 1을 0으로 반전시키는 것이다.


예를 들어 10라는 양의 정수를 1의 보수를 통해 음수로 변환시켜보겠다.

자바에서는 ~ 라는 기호를 통해 1의 보수를 시킬 수 있다.

a 라는 int형 변수에 10이라는 정수를 저장하고 a를 출력하고 2진수의 a, 

                                                               ~a, 2진수의 ~a를 출력해보았다.


그에 대한 결과값으로 a의 값 그대로 10, 그리고 10의 2진수 00001010 이 나왔다.

뒤이어 ~a의 값인 -11이 나오고 

~a를 이진수로 보여졌을때의 값인 11111111 11111111 11111111 11110101이 출력되었다.


1의 보수 변환 과정을 자세히 살펴보자.

우선 10을 2진수로 바꿔보자.

1 byte만 살펴보았을 때, 

10보다 작거나 같은 수 중에 제일 가까운 수는 8이다.

8에 해당하는 칸에 1을 넣어주고, 10에 8을 뺀 2에 가장 가까운 수는 2이다.

따라서 2에 해당하는 칸에 1을 넣어주고 2에 2를 빼면 0이 되므로 더 이상 1을 넣어줄 칸이 없다.

int형 변수 a의 값인 10에 해당하는 2진수는 00000000 00000000 00000000 00001010 이다.

여기서 0과 1을 반전시키면 11111111 11111111 11111111 11110101 이다.

이게 1의 보수를 한 값이다. 위의 이클립스 결과 화면창에도 보이듯이 같은 값이다.


2의 보수는 1의 보수 방법을 똑같이 한 후 마지막에 1을 더하는 것이다.

예시를 보자. 위의 사진 코드 및에 추가한 소스이다.

자바의 경우 ~가 아니면 2의 보수를 취하기 때문에 -a를 해주면 자동적으로 2의 보수를 하게 된다.

원래 a의 값에 -를 취해 -10이라는 값이 출력되었고 그 값을 2진수로 바꾼 것은 

11111111 11111111 11111111 11110110 이 나왔다.

아까 1의 보수로 바꾼 값에 1을 더해 나온 값과 같다.


1의 보수와 2의 보수에 대해서 좀 감이 잡히는가?

그렇다면 역으로 음수를 2진수에서 10진수로 보여지는 방법을 예시로 들어보겠다.


아까 -10을 2진수로 나타낸 것을 이용하여 10진수로 바꿔보겠다.

1. 0과 1을 전환한다.


2. 2진수를 10진수로 변환

3. 변환한 10진수에 +1 을 한다.

9 + 1 = 10


4. - 를 정수 앞에 붙인다.

-10 완성!


보수법. 알고나니 조금 쉬워진 느낌이 들지 않는가?

5개 정도 직접 손으로 풀고나면 머리에 들어오는 느낌이 날 것이다.