음수 표현 방법
- 부호절대값, 1의보수, 2의보수
- 컴퓨터는 덧셈만 할 수 있게 설계되어져 있음
그렇다면 뺄셈은? 2의 보수를 이용함
부호절대값
: 8비트 이진수에서 가장 왼쪽에 있는 비트를 부호비트
0이면 양수, 1이면 음수
ex) 00000011(2) -> 3(10)
10000011(2) -> -3(10)
(한 비트를 부호비트로 사용하기 때문에 8비트로 나타낼 수 있는 수가 상대적으로 적음)
표현 범위 : - (2^n - 1) ~ 2^n - 1
n의 보수
: n이 되기 위해 보충해줘야 하는 수
ex) 30의 100의 보수는 70
1의보수 (11111111 - 해당 수)
: 이진수의 각 자리 수가 1이 되기 위해 보충해줘야 하는 수
ex) 0 1 0 1 0 1 0 1 의 1의 보수는 1 0 1 0 1 0 1 0
비트를 반전 시킨 것과 마찬가지
ex) 13을 2의 보수방식으로 바꾸기
00001101 -> 11110010
표현 범위 : -(2^(n-1) - 1) ~ 2^(n-1) - 1
10진 양수 |
2진 양수 |
10진 음수 |
1의 보수 |
+0 |
00000000 |
-0 |
11111111 |
+1 |
00000001 |
-1 |
11111110 |
+2 |
00000010 |
-2 |
11111101 |
+3 |
00000011 |
-3 |
11111100 |
+4 |
00000100 |
-4 |
11111011 |
+5 |
00000101 |
-5 |
11111010 |
+6 |
00000110 |
-6 |
11111001 |
+7 | 00000111 | -7 | 11111000 |
2의보수(100000000 - 해당 수)
: 해당 수를 어떠 한 2의 제곱수에서 뺀 뒤 얻은 이진수
ex) 0 1 0 1 0 1 0 1 의 2의 보수는 1 0 1 0 1 0 1 1
1의보수를 취한 이진수에 1을 더한 것과 마찬가지
(캐리값(8자리에서 벗어난 값)은 계산에서 제외)
ex) 13을 2의 보수 방식으로 바꾸기
00001101 -> 11110011
표현범위 : -2^(n-1) ~ 2^(n-1) - 1
10진 양수 |
2진 양수 |
10진 음수 |
2의 보수 |
+0 |
00000000 |
0 |
1 00000000 |
+1 |
00000001 |
-1 |
11111111 |
+2 |
00000010 |
-2 |
11111110 |
+3 |
00000011 |
-3 |
11111101 |
+4 |
00000100 |
-4 |
11111100 |
+5 |
00000101 |
-5 |
11111011 |
+6 |
00000110 |
-6 |
11111010 |
+7 |
00000111 |
-7 |
11111001 |
- 2의 보수를 이용하여 뺄셈하기
양수는 이진양수로 표현하고 음수는 2의 보수로 표현하여 더하면 됨
=> 부호절대값 방식, 1의 보수 방식, 2의보수 방식은 모두 다 왼쪽 비트가 0이면 양수 1이면 음수로 취급
=> 부호절대값 방식, 1의보수 방식은 +0, -0 두가지이고 2의보수 방식은 0이 한개
위의 코드를 실행시켜보면 아래의 결과가 나옴
00111100을 반전시켰기 때문에 11000011이 나올거라고 예상하지만 그렇지 않음
int형이기 때문에 4바이트를 갖음
(원본 이진수)
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
원본 이진수를 반전시키면 위와 같은 결과가 나오는데 이 값은 2의 보수표현으로 -61임
이 -61에서 61을 이진수로 표현하면 111101이고 음수이기 때문에 -가 붙여져서 -111101이라고 결과가 나옴
따라서 코드 결과 이해가 가능함