해당 포스팅은 컴퓨터 사이언스 부트캠프 with 파이썬(양태환 저)를 보고 공부하며 개인적인 용도를 위해 정리한 글이다.
비트를 사용해 정수를 표현하기
정수 표현
실생활의 우리가 주로 사용하고 있는 수는 10 진수demical number이다.
0 ~ 9 까지를 한 자리에 나타낼 수 있으며 9를 넘는 수는 10 을 곱하여 다시 시작한다.
이때 자릿수가 커짐에 따라 10 의 거듭제곱으로 커지게 되며, 지수 부분이 적용 될 밑수base-number 가 10 이기 때문에 10진수라는 이름이 붙여졌다.
이와 마찬가지로 2진수는 0 ~ 1 까지를 한 자리에 나타낼 수 있는 셈법이며 1 을 초과하는 수를 나타낼 땐 2 를 곱하여 다시 시작한다.
자릿수가 바뀔 때마다 2 의 거듭제곱순으로 커지게 되며, 밑수가 2 이기 때문에 2 진수라는 이름이 붙었다.
- 10진수: \(... 10^5 + 10^4 + 10^3 + 10^2 + 10^1 + 10^0\)
- 2진수: \(... 2^5 + 2^4 + 2^3 + 2^2 + 2^1 + 2^0\)
\(5,028\) 이라는 수를 표현할 때,
10 진수는 \(5 * 10^3 + 0 * 10^2 + 2 * 10^1 + 8 * 10^0\)
2 진수는 $1 * 2^{12} + 0 * 2^{11} + 0 * 2^{10} + 1 * 2^9 + 1 * 2^8 + 1 * 2^7 + 0 * 2^6 + 1 * 2^5 + 0 * 2^4 + 0 * 2^3 + 1 * 2^2 + 0 * 2^1 + 0 * 2^0$
10 진수로는 네 자리, 2 진수로는 13자리 (13bit) 가 된다.
각 진법의 숫자 개수는 표현할 수 있는 값의 범위를 결정하는데 0 ~ 99 사이의 100가지 다른 수는 10 진수 숫자 2개로 표현 가능하다.
마찬가지로 2 진수에서도 비트의 개수로 표현할 수 있는 값의 범위를 정하는데, 예를 들면 2 비트는 0 ~ 3 까지의 수를 표현할 수 있다.
2 진수에서 가장 오른쪽에 있는 비트는 가장 작은 유효 비트 (LSB; Least Significant Bit),
가장 왼쪽에 있는 비트는 가장 큰 유효 비트 (MSB; Most Significant Bit) 라고 한다.
LSB
가 변경 되면 숫자가 가장 적게 변화하고 MSB
가 변경 되면 숫자가 가장 크게 변화하기 때문이다.
위에서 본 $5,028$ 는 13bit 라는 것을 알았는데, 이를 16비트 2진수로 표현하면
$0 0 0 1 0 0 1 1 \, 1 0 1 0 0 1 0 0$ 로 표현 할 수 있는데, 이 때 16 자리만큼 채우기 위해 앞에 0 을 붙이는 것을 리딩 제로leading zero 라고 한다.
$05,028$ 과 비슷한 의미이며 컴퓨터는 메모리를 할당할 때 미리 정해진 수의 비트를 한 덩어리로 사용하도록 만들어졌기 때문이다.
(이 덕분에 어떤 값을 표현하는데 필요한 최소한의 비트 수보다 더 많은 비트를 추가할 수 있다.)
2진수 덧셈
2 진수의 덧셈은 10 진수의 덧셈과 비슷하게 LSM
부터 MSB
쪽으로 연산하며 결과가 1보다 크면 1을 다음 자리로 올린다.
예를 들면 $1 1$ 과 $1 0$ 의 덧셈은 $1 0 1$ 이 된다.
이를 10 진수로 풀이해보면 $1 1$ 은 10 진수로 $(1 * 2^1) + (1 * 2^0) = 3$ 이고 $1 0$ 은 $(1 * 2^1) + (0 * 2^0) = 2$ 이기 때문에 $5$ 가 된다.
$5$ 을 2 진수로 표현하면 $(1 * 2^2) + (0 * 2^1) + (1 * 2^0) = 5$ 가 된다.
2 진 덧셈을 논리연산으로 풀이하면 다음과 같다.
A | B | A AND B | A + B | A XOR B | A | B |
---|---|---|---|---|---|---|
0 | 0 | 0 | 00 | 0 | 0 | 0 |
0 | 1 | 0 | 01 | 1 | 0 | 1 |
1 | 0 | 0 | 10 | 1 | 1 | 0 |
1 | 1 | 1 | 10 | 0 | 1 | 1 |
A 와 B 의 합연산은 A XOR B 의 값과 같으며 1, 1 인 경우에 1 XOR 1 이 0 인데 이는 두 비트를 더한 결과에서 원래의 위치에 넣을 값과 같다.
비트의 덧셈 연산 중 MSB 에서 올림이 발생했을 때, 오버플로over flow 가 발생한다.
음수 표현
부호비트 표기법
특정한 개수의 비트가 있을 때 MSB
를 부호로 표현한다.
0 일 때 양수, 1 일 때 음수.
$0001(+1) + 1001(-1)$ 을 계산하면 $1010(-2)$ 이 된다.
우리가 의도한 바는 $(+1) + (-1) = 0$ 이 되는 것이었는데 실제로는 $-2$ 가 되었다.
이러한 문제점 때문에 부호비트를 통해 음수를 표현하는 것은 잘 쓰이질 않는다.
1의 보수one’s complement
양수의 모든 비트를 뒤집는 방법이며, 부호비트 표기법과 비슷하게 부호비트와 나머지로 나눈다.
1 의 보수라는 문맥에서는 NOT
연산을 통해 보수를 얻는다.
그러나 위의 표기법도 부호비트 표기법과 마찬가지로 덧셈 연산이 쉽지 않기 때문에 현대 컴퓨터에서는 거의 쓰이질 않는다.
2의 보수two’s complement
$+ 1$ 을 했을 때 0 이 되는 비트 패턴을 찾고 $-1$ 이라고 표현을 하는 것이다.
4비트 수의 경우 $+1$ 의 경우 $0001$ 인데 $1111$ 을 $0001$ 에 더하면 $0000$ 이 된다.
이 때 $1111$ 을 $-1$ 패턴으로 사용한다.
2의 보수는 모든 비트에 NOT
연산을 수행하고 거기에 1 을 더하는 것이다.
이 때 MSB
를 넘어가는 값은 버린다.
예를 들어보면 $0010(2)$ 를 NOT
연산하면 $1101$ 이 되고 이 때 1을 더하면 $1110$ 이 되며 이를 $-2$ 이라고 하면 된다.
2의 보수는 1의 보수와 부호비트 표기법과 다르고 0 을 표기하는 방법이 하나이기 때문에 현대의 컴퓨터에서는 대부분 2의 보수를 많이 사용한다.