늘 알고 있다고 생각하지만,
조금만 호벼파보면 얼마 못가서 그 얕음이 낱낱이 드러나는 파트가 또 이 부분이 아닐까 싶다ㅠ
확실히 이해하고자 스스로 정리하는 컴퓨터의 음수 표현 (ft. 보수)
0. 보수
보수는 영어로 complement, 즉 '보충' 해주는 수 다.
이 수를 좀 더 깊이 이해하기 위해선 진법을 이해해야 하는데,
N진법에서 보수를 이야기함에 있어서는 크게 N의 보수와 N-1의 보수로 나누어 볼 수 있다.
사전적 정의를 풀어보며 출발하자면 다음과 같다
어떤 수 a에 {무언가}를 더했을 때, 깔끔한 [N진법의 수]를 만들어 냈다면
-> 그 {무언가}를 'a의 N의 보수'라고 부르자
어떤 수 a에 {무언가}를 더했을 때, 깔끔한 [N진법의 수 - 1]를 만들어 냈다면
-> 그 {무언가}를 'a의 N-1의 보수'라고 부르자
좀 더 쉽게 대입해보자, 10진법
어떤 수 4에 {무언가}를 더했을 때, 깔끔한 [10]을 만들어 냈다면
-> 그 {무언가, 6} 을 '4의 10의 보수'라고 부르자
어떤 수 4에 {무언가}를 더했을 때, 깔끔한 [9]를 만들어 냈다면
-> 그 {무언가, 5} 를 '4의 9의 보수'라고 부르자
연장 시켜보자
423 + ? = 1000 -> 577은 423의 10의 보수
423 + ? = 999 -> 576은 423의 9의 보수
라고 이해하면 되겠다
후를 위해 좀 더 나아가보자면,
보수를 b라고 했을 때 (bosu의 약자 b 아님 주의)
423 + b100 = 1000
b100 = 1000 - 423 ... (1)
423 + b99 = 999
= (1000 - 1)
b99 = 1000 - 423 - 1 ... (2)
b99 = b100 - 1 from (1)
or
b100 = b99 + 1
N의 보수는 N-1의 보수에 1을 더한 값
=
N-1의 보수는 N의 보수에 1을 제한 값
으로 이해할 수 있겠다
1. SMR
컴퓨터에서 처음 bit를 활용한 수를 표현하기 시작하면서
맨 앞자리 bit를 부호로 활용하는 SMR (Signed magnitude reporesentation)이 개발되었다
2번째~n번째 bit는 그대로 활용하되, MSB에 따라 양/음을 결정하는 방식이다
0000 0
0001 1
0010 2
...
0110 6
0111 7
1000 -0
1001 -1
...
1110 -6
1111 -7
대략 2진법의 표현 순서상 0~7 -> -0~-7 순으로 진행된다
이 표현방식은
- +0, -0이 존재
- MSB를 확인하고 음수임을 인지한 후 계산해야하는 번거로움
- 또한 뺄셈을 위한 별도의 뻴셈기를 만들어야 하는 번거로움 (위에랑 같은건가;)
- 음수의 두 수 비교연산에 다소 어려움 (-2 > -3 -> 1010 < 1011)
와 같은 단점을 갖고 있었다
2. 1's Complement
(누구의 아이디어였는지) bitwise NOT을 활용하여 음수를 표현하자는 획기적인 제안...
더해서 111...11을 만드는 맞대응의 1의 보수를 음수로 치게 되면 다음과 같이 표현되는데
0000 0
0001 1
0010 2
...
0110 6
0111 7
1000 -7
1001 -6
...
1110 -1
1111 -0
2진법의 표현 순서상 0~7 -> -7~-0 의 대칭 형태로 나타난다
- +0, -0이 여전히 존재
- 뺄셈을 음수의 덧셈으로 전환할 수 있음 (1의 보수 계산 후 덧셈)
- 각 1의 보수와 더했을 때, -0(111...11)이 나옴
- 음수 역시 내려가면서 커지므로 음수 간 비교연산도 용이
의 특징을 가질 수 있는데,
또 하나 특이한 점이라면 덧셈 후 표현 범위 외로 벗어나는 Carry가 발생했을 경우,
이를 그대로 LSB에 하나 더해주는 형태를 취해야 정확한 수식의 답을 얻을 수 있다
(이 carry를 end-around carry라고 부름)
이 부분을 조금 더 설명하자면,
0000 0
0001 1
0010 2
...
0110 6
0111 7
1000 -7
1001 -6
...
1110 -1
1111 -0
0000 0
0001 1
0010 2
...
0110 6
0111 7
계속 1씩 더해가며 두 cycle을 붙여 표현하면
계속 숫자가 커나가는 것을 알 수 있는데, (7 -> -7 일단 제외)
1111 (-0)에서 0000 (+0)으로 더해져 넘어가는 상황에서
더했는데, -0에서 0이 되어버리는 셈이므로,
이 때에는 ( = 즉 end-around carry가 발생했을 때에는 )
1을 한번 더 더해주는 것으로 하자 ( = carry를 LSB에 더하자 )
는 보완 규칙을 얻어낼 수 있었다.
3. 2's Complement
1945년에 노이만이 처음 제안한 2의 보수
앞서 살펴 보았듯이,
2의 보수는 1의 보수에 1을 더한 값으로 simplify할 수 있다
곧,
0000 0
0001 1
0010 2
...
0110 6
0111 7
1000 -8
1001 -7
...
1110 -2
1111 -1
표현할 수 있는 음수의 범위가 하나씩 밀려 늘어나게 되면서
순서대로 보자면, 0~7 -> -8~-1의 순서로 표현이 가능하다
이 아이는,
- 0이 오직 1개만 존재 (00...00)
- 여전히 뻴셈을 음수의 덧셈으로 전환할 수 있음 (2의 보수 계산 후 덧셈)
- 각 2의 보수와 더했을 때, 온전한 0 (00...00)이 나옴
- 역시 음수간 비교도 가능
- 심지어 -1 다음에 0이 순환형태로 표현되므로 계산 시,
end-around carry를 신경쓸 필요 없음
이 결과, 현대의 컴퓨터(라고 해봐야 1945년 부터;)는 2의 보수를 실제 정수 표현에 사용하고 있다.
2의 보수를 통한 표현을 쓰면서 몇 가지 확실한 특성과 재미난 일이 있다.
- n bit로 표현 가능 범위는 +2^(n-1)-1 ~ 0 ~ -2^(n-1) (음수가 하나 더 많이 표현 가능)
- 100....00이 가장 작은 (음)수를 나타냄 (순환하는 형태를 이해하자)
- 가장 작은 (음)수의 절대값을 씌우면 자기 자신이 리턴된다 (!!!)
abs 함수는 2의 보수를 만들어 리턴하도록 대부분 설계되어있다 (당연한 이야기?)
100...00 의 2의 보수는 1의 보수에 1을 더하는 값이므로
011...11 + 1 = 100...00
본인 자신이 된다 ㅋ
(순환 형태를 꼭 기억하자... 1의 보수는 데칼코마니 대칭, 거기에 1칸 아래로)
재미지네 ㅋㅋ 보수 ㅋㅋ
'코딩을 허자' 카테고리의 다른 글
[CS] 뎃씨멀의 모든 것 (0) | 2021.12.25 |
---|---|
[CS] 카피의 모든 것 (0) | 2021.12.24 |
[IoT] 삼성 SDS (SHN-8912) 월패드 성공기 2-1 : 인피니티워 (1) | 2020.09.20 |
[IoT] 삼성 SDS (SHN-8912) 월패드 성공기 1 (4) | 2020.05.03 |
[Spark + Scala] Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/spark/sql/SparkSession (0) | 2019.05.23 |