배우기 › 주제 6
수 체계: 2진수, 8진수, 16진수와 코드
읽는 시간 7분 · bitGateLab 팀
디지털 회로는 0과 1만 이해하지만, 여러분은 수량, 부호, 디스플레이의 숫자, 인코더의 위치를 표현해야 합니다. 여기서는 위치 기수법이 어떻게 동작하는지, 10진수·2진수·8진수·16진수 사이를 어떻게 변환하는지, 2의 보수로 음수를 어떻게 나타내는지, 그리고 전자 회로에서 아주 흔히 쓰는 두 가지 코드인 BCD와 그레이 코드를 어떻게 사용하는지 배웁니다.
위치 기수법
기수가 b인 위치 기수법에서 각 자릿수는 오른쪽에서 0부터 세는 자리 위치에 따라 b의 거듭제곱과 곱해집니다. 10진수 347은 3·102 + 4·101 + 7·100입니다. 다른 기수에서도 마찬가지입니다.
- 2진수(기수 2): 숫자는 0과 1이며 비트라고 부릅니다. 자리 가중치는 1, 2, 4, 8, 16, 32, 64, 128...
- 8진수(기수 8): 숫자는 0부터 7까지입니다. 8진수 한 자리는 3비트에 해당합니다.
- 16진수(기수 16): 숫자는 0부터 9까지와 A부터 F까지입니다(A = 10, B = 11, C = 12, D = 13, E = 14, F = 15). 16진수 한 자리는 4비트에 해당합니다.
혼동을 피하기 위해 기수를 아래 첨자(10102, 178, 3F16)나 0b, 0x 같은 접두사로 표시합니다.
진법 변환
임의의 진법에서 10진수로
각 자릿수에 그 자리의 가중치를 곱해 더합니다. 예를 들어 2F316 = 2·256 + 15·16 + 3·1 = 512 + 240 + 3 = 755입니다.
10진수에서 2진수로
2로 반복해서 나누며 나머지를 적습니다. 2진수는 아래에서 위로 읽습니다(마지막 나머지가 최상위 비트입니다). 다른 방법은 들어갈 수 있는 가장 큰 2의 거듭제곱을 거듭해서 빼는 것입니다.
2진수, 8진수, 16진수 사이
8 = 23이고 16 = 24이므로 10진수를 거칠 필요가 없습니다. 오른쪽부터 비트를 3개씩(8진수) 또는 4개씩(16진수) 묶고, 필요하면 왼쪽에 0을 채웁니다.
예제 1: 156을 2진수, 8진수, 16진수로 변환하기.
- 연속 나눗셈: 156/2 = 78 나머지 0; 78/2 = 39 나머지 0; 39/2 = 19 나머지 1; 19/2 = 9 나머지 1; 9/2 = 4 나머지 1; 4/2 = 2 나머지 0; 2/2 = 1 나머지 0; 1/2 = 0 나머지 1.
- 나머지를 아래에서 위로 읽으면 156 = 100111002입니다. 검산: 128 + 16 + 8 + 4 = 156.
- 8진수: 10 011 100 → 010 011 100 → 2 3 4. 결과 2348 (2·64 + 3·8 + 4 = 156).
- 16진수: 1001 1100 → 9 C. 결과 9C16 (9·16 + 12 = 156).
음수: 2의 보수
비트 수가 n인 레지스터에는 "마이너스" 부호를 둘 자리가 없으므로 약속을 정해 씁니다. 거의 모든 프로세서가 쓰는 방식이 2의 보수입니다. 최상위 비트는 음의 가중치 −2n−1을 가지고, 나머지 비트는 양의 가중치를 그대로 유지합니다. 8비트이면 범위는 −128부터 +127까지이고, 4비트이면 −8부터 +7까지입니다.
어떤 수의 음수를 구하려면:
- 양수를 모든 비트를 갖춰 적습니다.
- 각 비트를 반전합니다(이것이 1의 보수입니다).
- 1을 더합니다.
이점은 매우 큽니다. 부호를 위한 특별한 논리 없이 같은 가산기 회로로 덧셈과 뺄셈을 모두 할 수 있습니다. 0은 하나뿐이고(00000000), 최상위 비트가 그 수가 음수인지 바로 알려 줍니다.
예제 2: −45를 8비트로 나타내고 25 + (−12) 계산하기.
- 45 = 00101101. 반전하면 11010010. 1을 더하면 11010011 = −45.
- 가중치로 검산: −128 + 64 + 16 + 2 + 1 = −45.
- 이제 25 + (−12)입니다. 25 = 00011001; 12 = 00001100, 반전하면 11110011, 1을 더하면 11110100 = −12.
- 덧셈: 00011001 + 11110100 = 1 00001101. 비트 8에서 넘쳐 나오는 캐리(자리올림)는 버립니다.
- 결과: 00001101 = 13. 맞습니다.
BCD 코드
BCD(2진화 10진수, 8421 방식)에서는 10진수의 각 자리를 따로따로 4비트로 나타냅니다. 그래서 395는 0011 1001 0101로 씁니다. 395를 2진수로 변환한 것(1100010112)과는 다릅니다. BCD는 비트를 더 많이 쓰지만, 각 묶음을 나눗셈 없이 곧바로 7세그먼트 디스플레이 디코더에 보낼 수 있습니다. 1010부터 1111까지의 코드는 BCD에서 유효하지 않으며, 설계할 때 이 조합들은 보통 카르노 맵에서 무관 조건으로 다룹니다.
그레이 코드
그레이 코드에서는 한 값에서 다음 값으로 넘어갈 때 비트 하나만 바뀝니다. 일반 2진수에서는 7(0111)에서 8(1000)로 넘어갈 때 네 비트가 한꺼번에 바뀝니다. 센서가 바로 그 전환 순간에 값을 읽으면 잠깐 동안 어떤 중간값이든 보게 될 수 있습니다. 그레이 코드에서는 이런 오류가 생기지 않으므로 위치 인코더, 서로 다른 클럭 사이를 넘나드는 카운터, 카르노 맵의 머리글에 쓰입니다.
- 2진수에서 그레이 코드로: 최상위 비트는 그대로 복사하고, 그다음 각 비트는 해당 2진 비트와 그 왼쪽 2진 비트의 XOR입니다. 식으로는 g = b ⊕ (b를 오른쪽으로 한 자리 시프트한 값)입니다.
- 그레이 코드에서 2진수로: 최상위 비트는 그대로 복사하고, 그다음 각 2진 비트는 방금 구한 2진 비트와 그 자리의 그레이 비트의 XOR입니다.
| 10진수 | 2진수 | 그레이 | 10진수 | 2진수 | 그레이 |
|---|---|---|---|---|---|
| 0 | 0000 | 0000 | 8 | 1000 | 1100 |
| 1 | 0001 | 0001 | 9 | 1001 | 1101 |
| 2 | 0010 | 0011 | 10 | 1010 | 1111 |
| 3 | 0011 | 0010 | 11 | 1011 | 1110 |
| 4 | 0100 | 0110 | 12 | 1100 | 1010 |
| 5 | 0101 | 0111 | 13 | 1101 | 1011 |
| 6 | 0110 | 0101 | 14 | 1110 | 1001 |
| 7 | 0111 | 0100 | 15 | 1111 | 1000 |
예제 3: 2진수 1011을 그레이 코드로, 그리고 다시 2진수로.
- 첫 비트를 복사합니다: 1.
- 1 ⊕ 0 = 1; 0 ⊕ 1 = 1; 1 ⊕ 1 = 0. 그레이 = 1110.
- 되돌리기: 첫 비트를 복사합니다, b3 = 1. 이어서 b2 = 1 ⊕ 1 = 0, b1 = 0 ⊕ 1 = 1, b0 = 1 ⊕ 0 = 1. 2진수 = 1011.
표에서 10진수 11은 그레이 코드 1110으로 나와 있습니다. 일치합니다.
흔한 실수
- 8진수나 16진수로 바꿀 때 비트를 왼쪽부터 묶는 것. 항상 최하위 비트부터 묶습니다.
- 2의 보수에서 "+1"을 잊는 것. 반전만 하면 1의 보수가 되는데, 1의 보수에는 0이 두 개 있고 범위도 다릅니다.
- 레지스터가 부호 있는 수인데 11010011을 211로 해석하는 것. 같은 비트 패턴이 부호 없는 수로는 211, 부호 있는 수로는 −45입니다. 어떤 약속을 쓰느냐에 따라 달라집니다.
- BCD와 2진수를 혼동하는 것. 25는 BCD로 0010 0101이지만 2진수로는 11001입니다.
- 그레이 코드를 2진수로 바꿀 때 방금 계산한 2진 비트가 아니라 이웃한 그레이 비트와 XOR하는 것.
시뮬레이터에서 해 보기
입력과 출력 몇 개만 있으면 이런 표현을 "실시간으로" 볼 수 있고, XOR 게이트로 그레이 코드 변환을 확인할 수 있습니다.
- 입력 네 개를 비트 b3부터 b0까지로 놓고, 값을 볼 수 있도록 디스플레이나 LED 네 개를 연결합니다.
- XOR 게이트 세 개를 추가합니다: g2 = b3 ⊕ b2, g1 = b2 ⊕ b1, g0 = b1 ⊕ b0. 그리고 b3을 g3에 직접 연결합니다.
- 입력을 0000부터 1111까지 바꿔 가며, 한 값에서 다음 값으로 넘어갈 때 출력의 그레이 비트가 하나만 바뀌는 것을 관찰합니다.
- 회로의 진리표를 생성해 이 글의 표와 비교합니다.
연습문제
- 110101102를 16진수와 10진수로 변환하세요.
정답
1101 0110 = D616 = 13·16 + 6 = 214.
- 200을 2진수와 16진수로 변환하세요.
정답
200 = 128 + 64 + 8 = 110010002 = C816.
- −100을 8비트 2의 보수로 나타내세요.
정답
100 = 01100100; 반전하면 10011011; 1을 더하면 10011100. 검산: −128 + 16 + 8 + 4 = −100.
- 10진수 6을 4비트 그레이 코드로, BCD 0111 0010을 10진수로 변환하세요.
정답
6 = 0110; 그레이: 0, 0 ⊕ 1 = 1, 1 ⊕ 1 = 0, 1 ⊕ 0 = 1 → 0101. BCD 0111 0010은 72입니다.
회로가 이런 수를 어떻게 더하고 빼는지 보려면 2진 가산기로 이어 가세요.