곧휴가철인데 방에 쳐박혀서 암것도 안하고 있을라니 적적해서 간단히 2의 보수에 대해서 고등학교 수학 수준에서 설명을 해볼라 그래

왜 어렵게 2의 보수를 쓰는지, 2의 보수가 어떻게 생겨먹은건지 모르고 그냥 쓰는 아해들은 읽어보면 어렵지 않게 이해할 수 있을거야

일단은 1byte 로 표현가능한 숫자가 256 가지라는건 알지?

그래서 unsigned char의 경우에 0부터 255까지 표현 가능하다는 얘긴 많이 들었을거야 (sizeof(char) == 1이고, 1byte == 8 bit 라고 가정하자)

근데 char처럼 음수도 사용하고자 할때, 음수를 표현하는 가장 직관적인 방법은 아마도 최상위비트(MSB)를 부호 비트로 사용해서 표현하는 방법일거야

1이 0000 0001이니까 -1을 1000 0001 로 쓰는 방법인거지. 이게 1의 보수야.

1의 보수가 가진 문제점 중의 하나로 많이들 알고 있는게, 0000 0000은 +0이고, 1000 0000은 -0 으로 같은 0을 표현하는 방법이 2가지가 생긴다는 걸꺼야.

그런데 실제로 1의 보수가 가진 더 큰 문제점은 덧셈회로를 짤 때 생겨.(디지털 시스템 같은 과목을 들은 횽들은 논리회로로 ALU같은거 만들어보고 했을거야)

양수 두개를 더할때는 우리가 알고 있는 일반적인 덧셈 과정을 그대로 쓰면 돼.

1 + 1 = 
___0000 0001 +
___0000 0001
-------------
_= 0000 0010 = 2 가 되는 것처럼.

그런데 양수와 음수를 더할 때는 저 과정을 그대로 사용할 수가 없어.

간단하게 1이랑 -1을 더한다고 생각해보자. 1은 0000 0001 이니까 -1은 1의보수로 표현한다고 했을때 1000 0001 이 되겠지?

그럼 이 두 수를 더해보자.

_0000 0001 +
_1000 0001
-----------
= 1000 0010 이 되고, 1의 보수 표현방식을 따르면 1000 0010 은 -2가 되겠지? 1이랑 -1이랑 더했는데 결과가 -2가 되어버리는 요상한 일이 발생하는거야.

그러니까 1의 보수를 사용하면, 양수 + 양수, 양수 + 음수, 음수 + 음수 등등 여러 경우에 대해 덧셈회로를 다 따로 만들어야겠지?

여기서 음수의 표현방법을 바꿔서, 양수든 음수든 한 덧셈회로로 사용 가능한 방법을 생각해보자 이거야.

정상적인 고등학교 수학과정을 밟은 사람이라면 \'덧셈에 대한 역원\'이라는 말을 배운 적이 있을거야.

수학적으로 표현하자면, 어떤 수 a가 있을 때, a + x = 0 이 되면 x가 a의 덧셈에 대한 역원 이라는 거지.

그럼 1 + x = 0이 되는 x를 찾으면 x가 1의 덧셈에 대한 역원이라는거고, 그럼 x = -1이 되는거겠지?

쉽게 말하자면, 더해서 0이 되는 수를 찾자는거야.

1 은 0000 0001 인데, 여기서 어떤 수를 더해야 0이 될까?

0000 0001 + 1111 1111 = 0000 0000 이 되지? ( 1이 올림되는건 수의 표현 범위가 8 bit니까 잘려나간다고 생각하자)

1에 더했을때 0이 되는 수가 -1 이니까, -1 = 1111 1111 이라고 표현하면 될 것 같지 않아?

마찬가지로 -2에 대해서 똑같이 생각해보면 왜 -2 = 1111 1110 이 되는지 금방 알 수 있을겨.

이런식으로 음수를 표현하는게 2의 보수야.

2의 보수를 쓰면 앞에서 말한대로 양수든 음수든 간단한 덧셈회로를 이용해서 계산이 가능해지겠지? 그래서 2의 보수를 쓰면 unsigned char든, char든, 양수든 음수든 한 덧셈회로로 모두 덧셈을 수행할 수 있게 돼.

여기서 MSB가 1인 수는 음수고, MSB가 0인 수는 양수라고 하면, 흔히들 알고 있는 char의 표현 범위인 -128..127이 왜 고렇게 생겨먹게 된건지도 알 수 있을겨

한가지만 더 예를 들고 끝낼게. 2의 보수를 이용해서 2 + (-3) 을 계싼해보자.

2 = 0000 0010
-3= 1111 1101
--------------
___1111 1111 = -1

간단하게 쓸라했는데 쓰다보니까 어째 보기도 어렵고 쉬운 얘길 너무 어렵게 쓴 것 같네. 도움이 됐음 좋겠네