정수는 "자연수(양의 정수)", "0", "음의 정수"로 구성된 수 집합이다. 컴퓨터에서도 정수의 의미 자체는 동일하지만 컴퓨터는 2진수를 활용하여 수를 표현하기에 정수 표현 방법은 약간 다르다.
부호 없는 정수(Unsigned Integer)
부호 없는 정수는 말 그대로 부호를 생략한다는 의미로, 모든 숫자는 0 또는 양의 정수로 표현된다. 8비트로 부호 없는 정수를 표현하면 ~ 표현이 가능하다. 즉, n비트를 사용한 부호 없는 정수 표현은 0부터 까지이다.
오버플로우(Overflow)
8비트로 표현하는 부호 없는 정수의 경우 ~ 까지 가능한데 이때, 255를 넘어가는 숫자가 들어온다면, 컴퓨터는 틀린 값을 출력한다. 이를 "오버플로우(overflow)"라고 한다. 즉, 오버플로우는 표현할 수 있는 가장 큰 절댓값 수를 넘어서서 정확한 수를 표현할 수 없게 되는 경우를 말하는 것이다. 오버플로우가 일어나서 연산 결과가 틀리더라도 프로그램은 종료되지 않고 계속 수행되기에 이를 명시적으로 체크해야 한다.
CAUTION!
오버플로우는 꼭 부호없는 정수에서만 나타나는 것은 아니다. 부호 있는 정수와 실수에서도 오버플로우는 발생 가능하다.
부호 있는 정수(Signed Integer)
부호 있는 정수는 "음수의 표현"을 다루겠다는 의미를 가진다. 부호 있는 정수를 표현하는 방법에는"부호화 절대값 표현"과 "보수 표현"이 있다.
부호화 절댓값(Sign and Magnitude)
부호화 절댓값 표현은 MSB(Most Significant Bit: 가장 왼쪽의 비트)가 0이면 '0 또는 양의 정수'를 MSB가 1이면 '0 또는 음의 정수'를 나타내는 방식이다.
8비트를 이용하여 부호화 절댓값을 표현할 떄는 절댓값 계산을 위해 7비트까지만 사용할 수 있다. 즉, n비트를 사용한 부호 있는 정수 표현은 부터 까지이다.
이러한 부호화 절댓값 표현에는 문제점이 있는데, 첫 번째는 "부호화 절댓값 표현에는 +0과 -0, 즉 0이 2개가 존재한다"는 것이다. 두 번째는 "부호화 절댓값 표현을 통한 덧셈 연산은 아주 느리다"는 것이다. 이러한 문제점들을 보완하고자 "보수 표현"이 탄생하게 되었다.
보수 표현(Complement Representation)
보수는 "두 수의 합이 진수의 밑수(N)가 되게 하는 수"를 말한다. 예를 들어 "10진수 2"의 10의 보수는 "10진수 8"이고, "10진수 6"의 10의 보수는 "10진수 4"이다. n진법으로 표시된 정수를 기준으로 n-1의 보수 표현법과 n의 보수 표현법이 존재힌다.
대표적으로 컴퓨터가 사용하는 2진법에는 1의 보수와 2의 보수가 있는데 이에 대해서 알아보겠다.
1의 보수 표현
1의 보수는 "어떤 2진수의 비트를 반전"시켜서 얻을 수 있다. 즉, 0 -> 1, 1 -> 0로 바꾸는 것이다. (Ex: 2진수 1010의 1의 보수는 0101이다.)
이때, 1의 보수 표현에서는 0이 +0과 -0, 이렇게 2개로 존재한다.
2의 보수 표현
2의 보수는 "어떤 2진수의 비트를 반전시킨 후 결과값에 1을 더해서" 얻을 수 있다. 즉, 어떤 2진수를 1의 보수로 바꾼 후 제일 뒤에 1을 더해주는것과 같다. (Ex: 2진수 1010의 2의 보수는 0110이다.)
2의 보수 표현에는 0이 1개만 존재하기에 1의 보수 표현에 비해 음수를 1개 더 표현이 가능하다. 컴퓨터는 기본적으로 2의 보수 표현을 사용한다.
보수 표현 사칙 연산
- 덧셈: 2진수에서 덧셈은 10진수에서 덧셈과 계산 방식이 동일하다. (Ex: 2진수 0101 + 2진수 0110 = 2진수 1011)
- 뺄셈: 2진수에서는 뺄셈 계산이 불가능하기에 보수를 이용하여 계산해야 한다.
1의 보수 뺄셈
TIP!
가장 먼저 빼는 수의 1의 보수를 구한 후 더한다.
그 후, 덧셈결과에 자리올림이 생기면 최하위 비트에 1을 더한후 자리올림 된 수를 제거한다.
그 후, 덧셈결과에 자리올림이 생기지 않으면 "연산 결과"의 1의 보수를 구한 후 '-' 부호를 붙인다.
Ex) 2진수 1101 - 2진수 1001
=> 1101 + (1001의 1의 보수)
=> 1101 + 0110 = 10011
=> (최하위 비트에 1 더함 = 10100)
=> (자리올림 수 제거 = 0100)
=> 답은 0100이다.
Ex) 2진수 0101 - 2진수 0110
=> 0101 + (0110의 1의 보수)
=> 0101 + 1010 = 1111
=> (1111의 1의 보수 = 0)
=> (부호 붙여서 -0)
답은 -0이다.
2의 보수 뺄셈
TIP!
가장 먼저 빼는 수의 2의 보수를 구한 후 더한다.
그 후, 덧셈결과에 자리올림이 생기면 자리올림이 생긴 수를 제거한다, 그리고 그 값이 결과이다.
그 후, 덧셈결과에 자리올림이 생기지 않으면 "연산 결과"의 2의 보수를 구한 후 '-' 부호를 붙인다.
Ex) 2진수 1101 - 2진수 1001
=> 1101 + (1001의 2의 보수)
=> 1101 + 0111 = 10100
=> (자리올림 수 제거 = 0100)
=> 답은 0100이다.
Ex) 2진수 0101 - 2진수 1001
=> 0101 + (1001의 2의 보수)
=> 0101 + 0111 = 1100
=> (1100의 2의 보수 = 0100)
=> (부호 붙여서 -0100)
답은 -0100이다.