본문 바로가기
{ Computer Science }/Algorithm

2의 보수란?? 쉬운 설명으로 궁금증 해결.. (비트 연산)

by ggyongi 2021. 3. 17.
반응형

 
 
 
 
<2의 보수>
2의 보수: 컴퓨터가 음수를 저장하기 위해 사용하는 방법 중 하나.
예를 들어 4비트 머신을 생각해보자. 이 머신은 0000부터 1111부터 표현이 가능하다. 총 16개. 
양수만을 저장하고싶다면 숫자 0부터 15까지 차례대로 대응시켜 저장할 수 있겠지만,
문제는 음수도 저장이 필요하다는 점!
그래서 16개 중 절반을 음수를 위해 할당한다. 따라서 -8부터 7까지의 숫자를 저장하게 된다.
그리고 맨 앞의 비트는 부호 비트로 사용한다. 맨 앞의 비트가 0이면 양수고 1이면 음수.

십진수 2진수 십진수 2진수
-8 1000 0 0000
-7 1001 1 0001
-6 1010 2 0010
-5 1011 3 0011
-4 1100 4 0100
-3 1101 5 0101
-2 1110 6 0110
-1 1111 7 0111

그럼 다음과 같은 궁금증이 생긴다.
 
Q1) 십진수를 2진수로 어떻게 바꿀 수 있을 까??
ex) 7   -> ??
ex) -7  -> ??
 
양수의 경우 이미 중학교때 이진수 변환법을 배웠다. 
예를 들어 7을 2진법으로 나타내고 싶으면 7을 2로 반복하여 나누면서 나오는 나머지를 거꾸로 읽어주면 된다. 자세한 설명은 생략. 따라서 7의 2진수는 0111 이라는 것을 알아낼 수 있다. 
 
음수일 경우에는 우선 양수의 2진수를 찾는다. 즉 -7의 2진수이 궁금할 때 우선 7의 2진수를 찾자. 
7의 2진수는 0111이다. 그리고 중요한 연산 하나가 등장한다. 그것은 바로 2의 보수 연산이다.
2의 보수 연산은 양수를 음수로, 음수를 양수로 바꿔주는 연산이다. 즉 부호를 바꿔주는 연산!
방법은 다음과 같다. 'NOT x'에서 1을 더해주면 끝. 간단하다.
그렇다면 여기서 'NOT x'은 무엇인가? 비트가 0이면 1로, 비트가 1이면 0으로 바꿔주는 연산이다.
이제 0111에 2의 보수 연산을 적용하면 다음과 같아진다. NOT을 하면 1000이 되고 여기에 1을 더해주면 1001이 된다. 최종적으로 -7의 2진수는 1001이 되는 것이다. 위의 표를 보면 맞게 구했음을 알 수 있다.
 
0111 ----------(2의 보수 연산)-----> 1001
( 7 ) -----------(양수->음수)--------> ( -7)
 
이번에는 4비트가 아닌 16비트, 32비트 등 더 큰 비트에서 생각해보자.
12의 2진수는 0000....1100이다.
NOT 연산 = 1111....0011
2의 보수 연산 = 1111....0100
따라서 -12는 1111....0100이 된다. 
 
 
Q2) 2진수를 알 때 십진법으로 어떻게 바꿀 수 있을 까??
ex) 0000....0110 -> ???
ex) 1111....0100 -> ???
 
부호비트가 0이면, 즉 맨 앞의 비트가 0이면 그 수는 양수라는 뜻이다. 양수의 경우 십진법으로 바꾸는 방법을 중학교 때 배웠다. 0110의 경우 1*0 + 2*1 + 4*1 = 6이 된다. 
 
부호비트가 1이면, 즉 맨 앞의 비트가 1이면 그 수는 음수라는 뜻이다. 음수의 경우 2의 보수 연산을 해준다. 
예를 들어 1111....0100이 십진법으로 뭔지 궁금하다고 했을 때, 우선 이 수가 음수임을 인지하고 
2의 보수 연산을 하면 0000....1100이 된다. 이 수는 12다. 따라서 알고자했던 1111....0100은 -12가 된다.
이유는 2의 보수 연산이 부호를 바꿔주는 연산이라고 말했었기 때문!!
 
<다른 예시> 1101이 궁금할 때
1101 ----------(2의 보수 연산)-----> 0011
( -3 ) <---------(음수로 변환)-------- ( 3 )
 
 
Q3) 어떤 수의 2의 보수는 어떻게 알아낼까?
위에서 배웠던 것을 적용하면 이제 매우 쉬워진다.
 
예를 들어 7의 2의 보수를 구해보자. 7은 0111이고 2의 보수 연산을 적용하면 1001이다. 즉 7의 2의 보수는 1001이다. 1001은 십진수로 표현하면 -7과 같다.
 
또 다른 예로 -6의 2의 보수를 구해보자. 그냥 6을 구해주면 되는 것이다. 6는 0110이다. 즉 -6의 2의 보수는 0110이다.
 
 
 
Q4) 왜 이름이 2의 보수일까??
다음을 보면 감이 올 수도 있다.
 
4비트에서
7은 0111이고 -7은 1001이다. 더하면 10000이 된다.
4는 0100이고 -4는 1100이다. 더하면 10000이 된다.
3은 0011이고 -3은 1101이다. 더하면 10000이 된다.  
전부다 10000이네?
 
8비트에서
1은  00000001이고 -1은 11111111이다. 더하면 10000000이 된다.
10은 00001010이고 -10은 11110110이다. 더하면 100000000이 된다.
33은 00100001이고 -32는 11011111이다. 더하면 100000000이 된다.
 
즉 두 수를 더하게 되면 최대 비트 크기보다 크면서 가장 작은 2의 거듭제곱 수가 나온다. 약간 이런 느낌으로 2의 보수라고 이름지은 것 같다. 
 
 
Q5) NOT x = -x-1인 이유는??

>>>print(~7)
-8

~는 비트 연산자 NOT을 뜻한다. 코드에 print(~7)을 하고 실행을 시키면 결과값으로 -8이 출력된다. 왜 그럴까??
 
앞에서 우리는 2의 보수 연산이 NOT 연산에 1을 더해주면 된다고 배웠다.  
(2의 보수 연산) = (NOT 연산) + 1     <<<<<이 식을 좀 변형하면?
(NOT 연산) = (2의 보수 연산) -1       <<<<<이러한 결과를 얻음.
 
예를 들어,
7은 0000....0111이다. NOT 연산을 하면 1111....1000이 된다. 
그럼 1111....1000은? 일단 1로 시작하니 음수고, 2의 보수 연산하면 0000....10000이므로 8이 되고 따라서 1111....1000은 -8이 된다. 
즉 NOT x = -x-1이 된다.  
 
 
참고:
<파이썬 알고리즘 인터뷰> 박상길 지음, 정진호 일러스트, 책만, 2020(https://www.onlybook.co.kr/entry/algorithm-interview)

 

다른 글 구경하기:

https://yiyj1030.tistory.com/562

 

2022년 회고

2021년 회고를 작성한 날짜를 확인해보니 2022.1.28이고 오늘이 2023.2.5이니 거의 1년만에 회고를 작성하는 것이라 볼 수 있다. 작년 회고: https://yiyj1030.tistory.com/m/456 2021년 회고1월에는 별 생각없이

yiyj1030.tistory.com

 

 

비전공자 네카라 신입 취업 노하우

시행착오 끝에 얻어낸 취업 노하우가 모두 담긴 전자책!

kmong.com

댓글