Digital Logic Toolkit — BCD converter
BCD Converter
Binary-coded decimal in every storage layout, with the nibble map, the validity check and the +6 correction that BCD addition needs.
Mode
Packing
Packed BCD gives each digit one nibble; unpacked gives each digit a whole byte. Neither changes the digits.
Input
BCD
01011001
Plain binary
111011
6 bits against 8 in BCD
59 in packed BCD
Each decimal digit becomes its own 4-bit group with weights 8-4-2-1. The six patterns 1010..1111 are never produced.
| digit | 8421 code | placement |
|---|---|---|
| 5 | 0101 | high or low nibble of a byte |
| 9 | 1001 | high or low nibble of a byte |
packed BCD01011001
compare with plain binary111011— BCD is longer: it trades density for digit-by-digit decimal arithmetic
Notation used on this page
- Digits are written most significant first. Each digit occupies its own group with weights 8-4-2-1.
- The six patterns 1010 to 1111 are never produced by BCD and are invalid input.
- In BCD addition the digits are numbered from the least significant, so digit 0 is the units digit.
Start from a worked example
What BCD is
BCD is not a way of writing a number in binary. It is a way of writing each decimal digit in binary and keeping the digits separate.
Each digit gets four bits with the ordinary weights 8-4-2-1, so 0 is 0000 and 9 is 1001. Four bits can hold sixteen patterns and only ten digits exist, so six patterns are unused — and that gap is where both the validity rule and the addition correction come from. 59 in packed BCD is 0101 1001, while 59 in plain binary is 00111011: different bits for the same number, which is the whole point.
Decimal to BCD
Encode each digit independently and concatenate: 1234 becomes 0001 0010 0011 0100. No carrying, no division, no dependence between digits — which is exactly why a display driver likes it.
BCD to decimal
Split into nibbles and read each as a digit: 0x12 0x34 is 1, 2, 3, 4 → 1234. A correct converter validates while it reads, because six of the sixteen nibble values do not name a digit; a decoder that silently accepts them is inventing an answer.
Packed, unpacked, zoned and signed
The digits are the same in all four layouts; what differs is how they are laid into bytes.
| Layout | Shape | Example |
|---|---|---|
| Packed | Two digits per byte, more significant digit in the high nibble. | 1234 → 12 34 |
| Unpacked | One digit per byte, in the low nibble, high nibble zero. | 1234 → 01 02 03 04 |
| Zoned | One digit per byte with a zone nibble that makes the byte an ASCII digit. | 1234 → 31 32 33 34 |
| Signed packed | Packed, with a final sign nibble: C positive, D negative, F unsigned. | −1234 → 01 23 4D |
- An odd digit count in packed BCD is left-padded with a zero nibble, so 123 is
01 23. - The sign nibble is the last nibble:
0xCis positive,0xDis negative and0xFmeans unsigned. This is the IBM and COBOL convention.
The six invalid codes
1010 through 1111 are not digits. Three of them are legal sign nibbles in signed packed BCD, which is why the same byte can be valid or invalid depending on the layout you declared: 12 3C is 123 with a positive sign under signed packed, and an invalid fourth digit under plain packed.
| Nibble | Reading |
|---|---|
| 1010 | 10 — no decimal digit |
| 1011 | 11 — no decimal digit |
| 1100 | 12 — no decimal digit (but a valid positive sign nibble) |
| 1101 | 13 — no decimal digit (but a valid negative sign nibble) |
| 1110 | 14 — no decimal digit |
| 1111 | 15 — no decimal digit (but a valid unsigned sign nibble) |
BCD addition and the +6 correction
Add the nibbles as ordinary binary. If a nibble sum exceeds 9, or if it produced a carry out of the nibble, add 6 to it and carry 1 into the next digit. 25 + 48: 5 + 8 = 13, which is above 9, so 13 + 6 = 19 → digit 3 with a carry; 2 + 4 + 1 = 7, which needs no correction. The answer is 0111 0011 = 73.
Six is the right correction because four bits count to sixteen and a decimal digit counts to ten: the nibble is running six ahead of the decimal it should be showing, and adding six pushes it past the invalid range and into the carry. The trap is 8 + 8 = 16 = 10000, whose low nibble is 0000 — a perfectly valid-looking 0 — and which is only caught by the carry-out half of the rule.
In hardware the condition is C = C₄ + Q₃Q₂ + Q₃Q₁, feeding a second four-bit adder that adds 0110. That circuit is built from the same full adders as any other ripple.
BCD subtraction
Subtraction uses 9’s or 10’s complement, exactly as two’s complement does in binary. For 72 − 27: the 9’s complement of 27 is 72, the 10’s complement is 73, and 72 + 73 = 145. The carry out of the most significant digit means the result is positive, so discard it and the answer is 45. With no carry out, the result is negative and is the 10’s complement of the magnitude.
BCD versus binary: what it costs and what it buys
BCD spends about 20% more storage than plain binary for the same range, because four bits carry only 10 of their 16 patterns. In exchange it never has a conversion error, digit extraction for a display is a nibble mask rather than a division, and the precision is unbounded.
BCD has no word width. A 20-digit value is 10 bytes and a 200-digit value is 100 bytes; nothing overflows at 64 bits. 2⁶⁴ − 1 is 18446744073709551615 — twenty digits, and therefore exactly ten packed bytes. The number base converter shows the same value in plain binary for comparison.
Where you will meet it
- COBOL’s
COMP-3data type is signed packed BCD. - IBM z/Architecture has packed-decimal instructions in hardware.
- The x86
DAAandAAAinstructions exist to apply exactly the +6 correction above. - Seven-segment display drivers take a BCD nibble per digit.
- DS1307-class real-time-clock chips hold their registers in BCD.
Excess-3 and the other decimal codes
This page implements natural 8421 BCD, and “BCD” unqualified means 8421. Other decimal codes exist and are taught alongside it: Excess-3 adds 3 to each BCD digit, which makes the code self-complementing, and 2421 re-weights the nibble for the same reason. They are named here so that a different answer in your textbook has an explanation rather than being a contradiction.
Notation used on this page
- Most significant digit first, left to right; nibbles are written most significant bit first.
- Packed BCD holds the more significant digit in the high nibble.
- An odd digit count is left-padded with a zero nibble.
- The sign nibble is the last nibble:
0xCpositive,0xDnegative,0xFunsigned. Hexadecimal is upper case.
Sources
8421 BCD is a convention with no single canonical citation and is stated here as a definition. The sign-nibble values are attributed to the IBM and COBOL convention: the same values appear in z/Architecture and in ISO/IEC 1989 without either being their origin, and naming a document as the source would be inventing a provenance.
Worked examples
- 259 → packed BCDintrofour bits per decimal digit
- BCD 1001 0111 → decimalintrodecode each nibble separately
- Is 1010 valid BCD?coresix wasted patterns per nibble
- BCD addition: 25 + 48corethe +6 correction
- BCD addition needing two corrections: 99 + 99corecorrections cascade
- Packed versus unpacked BCD for 259examtwo digits per byte, or one
- BCD 0001 0010 0011 → pure binaryexamthe conversion that needs real arithmetic
- Excess-3 code for the digit 5edge casea self-complementing alternative