BCD(이진화 십진수): 기초 설명
BCD는 각 십진 숫자를 4비트로 인코딩합니다. 패킹·언패킹 형식, +6 덧셈 보정, 십진 스케일링, 실용적인 트레이드오프를 알아봅니다.
요약: 이진화 십진수(BCD)는 각 십진 숫자 0
9를 4비트 니블에 저장하고 10101111은 사용하지 않습니다. BCD 한 자리 가산기는 원시 이진 합이 9를 넘거나 캐리 출력이 생기면 +6 보정을 적용합니다. BCD는 저장된 십진 숫자를 정확히 보존하지만, 유한 정밀도 나눗셈과 스케일링에는 여전히 명시적인 반올림 규칙이 필요합니다.
이진수와 십진수는 자릿값의 소인수가 서로 다르므로, 0.1을 비롯한 많은 유한 십진 분수는 유한한 이진 전개를 갖지 않습니다. 이진화 십진수는 십진 숫자를 직접 저장합니다. 이 방식은 최초의 이진 분수 표현 오차를 피하지만, 형식에 담을 수 있는 자릿수를 넘어서는 연산 결과에는 여전히 스케일, 정밀도, 반올림을 정해야 합니다.
이진화 십진수란?
BCD는 0부터 9까지 각 십진 숫자를 각각의 4비트 이진 코드로 나타냅니다. 4비트는 16개 패턴을 인코딩할 수 있지만 BCD는 처음 열 개만 사용합니다.
| 십진수 | BCD 니블 |
|---|---|
| 0 | 0000 |
| 1 | 0001 |
| 2 | 0010 |
| 3 | 0011 |
| 4 | 0100 |
| 5 | 0101 |
| 6 | 0110 |
| 7 | 0111 |
| 8 | 1000 |
| 9 | 1001 |
남은 여섯 패턴인 1010부터 1111까지, 즉 순수 이진수에서 값 10부터 15까지는 BCD에서 유효하지 않습니다. 회로가 이 패턴 중 하나를 만들었다면 한 자리가 오버플로했거나 잘못된 입력을 받았다는 뜻이며, BCD 가산기는 이 경우를 검출하고 보정해야 합니다.
여러 자리 십진수는 니블을 이어 붙여 인코딩합니다. 예를 들어 327은 다음과 같습니다.
9비트를 쓰는 순수 이진 표현 과 비교하면 BCD는 12비트를 씁니다. BCD는 자릿수 중심 표현을 보존하고 일부 십진 인터페이스를 단순하게 하는 대신 비트를 더 사용합니다.
패킹 BCD와 언패킹 BCD
일반적인 저장 배치는 두 가지입니다.
언패킹 BCD는 바이트마다 십진 숫자 하나를 저장합니다. 하위 니블에는 숫자가, 상위 니블에는 0 또는 ASCII 스타일 태그가 들어갑니다. 초기 IBM과 x86 BCD 명령에서의 0x30 태그는 곧바로 인쇄 가능한 ASCII 숫자를 만듭니다. 언패킹 BCD는 저장 공간의 절반을 낭비하지만 출력하기는 아주 쉽습니다.
패킹 BCD는 바이트의 각 니블에 숫자 하나씩, 한 바이트에 두 십진 숫자를 저장합니다. 패킹 BCD에서 327은 0x03 0x27의 두 바이트를 차지합니다. 패킹 BCD는 두 배 더 조밀하며, 하드웨어 BCD 가산기와 x86 DAA/DAS 명령 내부에서 쓰이는 형식입니다.
| 형식 | 숫자 327 | 바이트 | 밀도 |
|---|---|---|---|
| 언패킹 | 0x03 0x02 0x07 | 3 | 1자리/바이트 |
| 패킹 | 0x03 0x27 | 2 | 2자리/바이트 |
| 순수 이진수(16비트) | 0x01 0x47 | 2 | 전체 범위 |
16비트에 들어가는 값(최대 65,535)의 경우 순수 이진수는 밀도 면에서 패킹 BCD와 같으면서도 10,000개가 아니라 65,536개의 서로 다른 값을 인코딩합니다. 비용은 십진수와 정확히 일치해야 하는 산술 연산을 해야 할 때에야 다시 나타납니다.
BCD가 존재하는 이유
이진수가 더 조밀하다면 BCD를 왜 쓸까요? BCD를 계속 쓰게 하는 이유는 세 가지입니다.
저장된 십진 숫자의 정확성. 십진수 0.1은 종료되는 이진 표현이 없습니다. 소수점 위치가 형식의 일부라면 BCD는 0.1을 정확히 저장할 수 있습니다. 산술이 정확한 것은 수학적 결과가 선택한 자릿수와 스케일에 들어맞을 때뿐이며, 나눗셈과 다른 비종료 결과에는 여전히 반올림이 필요합니다. IEEE 754 부동소수점에서 이 절충의 이진 측면을 다룹니다.
간단한 표시 변환. 디지털 시계나 계산기는 각 BCD 니블을 작은 룩업 디코더에 통과시켜 7세그먼트 표시기를 구동합니다. 10으로 나누거나 반복 뺄셈 루프나 소프트웨어 변환을 할 필요가 없습니다. 이 장점 때문에 후속 글에서 다룰 BCD-7세그먼트 디코더를 사용합니다.
십진 업무 규칙. 금융과 계량 응용 프로그램은 종종 십진 스케일과 반올림을 명시합니다. 패킹 십진수, COBOL COMP-3, 십진 부동소수점, 스케일 이진 정수는 모두 가능한 표현입니다. BCD는 자릿수 단위 저장이나 인터페이스가 중요할 때 유용하지만, 규제가 BCD를 보편적으로 의무화하는 것은 아닙니다.
BCD 숫자 덧셈: +6 보정
BCD 덧셈은 보통 4비트 이진 가산기(복습은 4비트 리플 캐리 가산기 글 참조)를 사용한 다음, 9보다 큰 결과를 고치는 십진 보정 단계를 거칩니다.
규칙은 간단합니다. 두 BCD 숫자를 4비트 이진수처럼 더한 뒤 다음을 적용합니다.
- 이진 합이 9 이하이고 캐리 출력이 없으면 BCD 결과는 이진 합 그대로입니다.
- 이진 합이 9보다 크거나 4비트 가산기에서 캐리 출력이 있으면, 보정을 위해 6(
0110)을 더하고 다음 자리로 캐리를 전달합니다.
왜 6일까요? BCD가 여섯 개의 유효하지 않은 패턴 1010~1111을 건너뛰기 때문입니다. 이 범위 안이나 그 너머에 놓인 이진 합은 BCD 번호 체계에서 정확히 여섯 위치 앞서 있으므로, 6을 더하면 올바른 위치로 되돌아가며 십진 산술에 맞는 캐리가 나옵니다.
예제: 7 + 5
피연산자를 인코딩하여 4비트 이진수로 더합니다.
결과 1100은 이진수로 12이며, 유효하지 않은 BCD 패턴 중 하나입니다. +6 보정을 적용합니다.
보정 결과 0001 0010은 BCD에서 12입니다. 십의 자리로 올림이 하나 가고 일의 자리가 2가 된 것으로, 십진 산술이 내놓아야 할 바로 그 결과입니다.
예제: 8 + 9
4비트 가산기는 캐리 출력과 함께 0001을 만듭니다. 0001은 유효한 BCD 숫자로 보이지만 캐리 출력이 +6 보정을 일으킵니다.
최종 결과 0001 0111은 BCD의 17입니다. 보정 없이 원시 캐리와 하위 니블을 이어 붙이면 0001 0001이 되고, BCD 디코더는 이를 17이 아니라 11로 읽습니다.
“보정 필요”의 일반 검출 조건은 다음과 같습니다.
여기서 은 4비트 이진 합입니다. 두 AND 항은 유효하지 않은 여섯 패턴 1010~1111을 함께 포괄하고, 은 합이 이미 15를 넘어 순환한 경우를 포착합니다.
하드웨어: 한 자리 BCD 가산기
한 자리 BCD 가산기는 4비트 이진 가산기 두 개와 작은 보정 검출 회로로 구성됩니다.
A[3:0] B[3:0]
| |
v v
+-----------------+
| 4-bit adder #1 | <-- ordinary binary add (see /docs/adder)
+-----------------+
S[3:0] C_out
| |
+--+--+--+
| |
v v
+----------+
| detect | --> adjust = C_out OR (S3·S2) OR (S3·S1)
+----------+
|
v 0110 if adjust, else 0000
+-----------------+
| 4-bit adder #2 | <-- adds the correction
+-----------------+
|
v
BCD result, BCD carry-out
첫 번째 가산기는 원시 이진 덧셈을 수행합니다. 검출 블록은 adjust 신호를 계산합니다. 두 번째 가산기는 중간 합에 0 또는 6을 무조건 더합니다. BCD 캐리 출력은 adjust 신호 자체입니다. 6을 더해야 할 때마다 다음 십진 자리로 1도 전달하기 때문입니다. 이 블록을 개 데이지 체인으로 연결하면 자리 BCD 리플 가산기가 됩니다. 더 넓은 숫자와 보정 단계를 쓴다는 점만 빼면 구조는 이진 전가산기와 반가산기 체인과 같습니다.
가산기 블록 두 개와 검출 논리로 이를 만들고, 결과를 숫자 표시기에 연결할 수 있습니다. 입력은 유효한 BCD 숫자 0~9로 제한하세요. 보정식은 유효하지 않은 입력 니블을 일반적으로 정화하는 식이 아닙니다.
BCD 뺄셈
뺄셈도 같은 패턴을 따르지만 이진수의 2의 보수 대신 9의 보수 또는 10의 보수를 사용합니다. 를 계산하려면 다음과 같이 합니다.
- 각 숫자 를 로 바꿔 의 9의 보수를 구합니다.
- 결과를 BCD 덧셈으로 에 더합니다.
- 최종 캐리 출력이 생기면 결과에 1을 더합니다(10의 보수 보정). 캐리는 양수 결과를 뜻합니다.
- 캐리 출력이 없으면 결과는 음수이므로 다시 보수를 취해 크기를 구합니다.
9의 보수는 십진수에서 1의 보수가 이진수에서 하는 것과 같은 역할을 하고, 10의 보수는 2의 보수의 십진 대응물입니다. BCD ALU에는 뺄셈 쪽에도 같은 보정 단계가 필요합니다.
BCD의 단점
장점에는 실제 비용이 따릅니다.
저장 오버헤드. 십진 숫자 하나마다 4비트가 필요하므로 4바이트로는 최대 99,999,999만 인코딩할 수 있습니다. 순수 이진수에서 같은 32비트는 약 42억 9천만까지 나타냅니다. 표현 범위가 약 43배 넓습니다. 과학·그래픽 작업에서는 BCD가 낭비입니다.
더 많은 산술 작업. 한 자리 덧셈마다 이진 덧셈, 보정 검출, 보정이 필요합니다. 일부 레거시 x86 십진 보정 명령은 64비트 모드에서 사용할 수 없습니다. 패킹 십진수, 십진 부동소수점, 스케일 정수 중 무엇이 가장 빠른지는 ISA, 작업 부하, 라이브러리, 요구 의미론에 따라 달라집니다.
기본 분수 지원 부재. 여기서 설명한 BCD는 정수를 인코딩합니다. 분수 BCD에는 관례로 소수점을 고정하거나, 세 숫자를 더 조밀한 코드로 묶는 고밀도 패킹 십진수 또는 IEEE 754-2008 십진 부동소수점으로 옮겨야 합니다. 이런 인코딩의 역사는 초기 이진수 체계와 십진수·이진수 중 무엇으로 셀지에 관한 오랜 논쟁으로 이어집니다.
BCD가 여전히 쓰이는 곳
계산 자체는 십진이 아니더라도 입력과 출력이 십진인 곳에서는 BCD가 살아남습니다.
- 디지털 시계와 손목시계. 24시간 시계는 시·분·초를 BCD 여섯 자리로 저장합니다. 카운터 칩이 초를 증가시키고, 작은 비교기가 60을 검출해 분으로 넘깁니다. 같은 패턴으로 60분과 24시간을 처리합니다. 각 자리는 BCD-7세그먼트 디코더를 거쳐 7세그먼트 LED를 구동합니다.
- 계산기. 숫자 중심 산술은 십진 입력과 표시를 단순하게 할 수 있지만, 계산기 구현은 이진수와 다른 내부 표현도 사용합니다.
- 산업용 제어 패널. 썸휠 스위치는 BCD를 직접 출력하고 PLC 입력은 변환 없이 BCD를 읽습니다.
- 엔터프라이즈 시스템. 패킹 십진수를 지원하는 아키텍처와 언어는 고정 스케일 업무 데이터와 COBOL 작업 부하에서 여전히 유용합니다.
- 계량기와 판매 시점 장비. 십진 표시와 정해진 반올림 규칙은 숫자 중심 형식을 편리하게 만들 수 있지만, 구현 선택은 다양합니다.
교훈은 더 넓게 적용됩니다. 문제 영역이 본래 십진이라면 자릿수를 명시적으로 인코딩하는 편이 매 연산마다 진법을 변환하는 것보다 나을 때가 많습니다. 이 논리는 기저 CPU가 이진수로 동작하더라도 오늘날 금전 처리 소프트웨어에서 고정소수점 정수 산술을 지지하는 근거이기도 합니다.
시뮬레이터에서 해 보기
깔끔한 연습 과제는 한 자리 BCD 가산기를 만들고 보정이 동작하는 모습을 보는 것입니다.
- 4비트 입력 레지스터 , 를 가산기 블록에 연결합니다. 원시 5비트 합을 표시합니다.
- , , 의 OR인 검출 논리를 만듭니다.
- 검출 신호로 상수 0110을 두 번째 가산기에 게이팅하고, 첫 번째 합에 더합니다.
- 보정 결과의 하위 니블을 숫자 표시기에 연결합니다. BCD 캐리 출력은 별도 숫자에 연결합니다.
- , 를 훑습니다. A
F 기호가 한 번도 나타나지 않고 표시기가 두 자리에서 018을 읽는지 확인합니다.
더 넓은 값에는 두 번째 BCD 가산기 블록을 이어 연결합니다. 첫 번째 캐리 출력은 이진 리플 체인처럼 두 번째의 캐리 입력이 됩니다.
다음 내용
한 자리 BCD 가산기는 읽을 수 있어야 유용합니다. 다음 글인 BCD-7세그먼트 디코더: 숫자에서 표시까지는 BCD 진리표에서 세그먼트 구동 부울식을 유도하고 실제 표시기에 결과를 배선하는 방법을 보여 줍니다. 앞서 다룬 디코더 기초를 토대로 합니다. 같은 문제의 이진 측면을 보고 싶다면 IEEE 754 부동소수점 해설에서 이진 분수의 장점을 살피고 금융 코드가 십진수를 선택하는 이유를 확인할 수 있습니다.
4비트 이진 카운터 템플릿을 열어 BCD 가산기에 카운팅 입력을 넣고, 10번째 틱마다 보정이 작동하는 모습을 보세요. +6의 작동을 가장 직접적으로 볼 수 있는 방법입니다.



