Binary-coded decimal (BCD)
Storing decimal digits one nibble each
Binary-coded decimal (BCD) stores each decimal digit in its own 4-bit group using the 8421 weights, so the digits 0 to 9 map to 0000 to 1001 and the six patterns 1010 to 1111 are unused.
Builds onBinary numbers
Binary packs a whole number into one continuous string of bits, so decimal
59 becomes 0011 1011. That is dense and efficient, but it scrambles the decimal digits together: there is no 5 and no 9 to be found in 0011 1011. Binary-coded decimal (BCD) takes the opposite approach. It keeps each decimal digit in its own group of four bits, coded just like a small binary number, so the digits stay visible and separate.Think of an old mechanical odometer or a price display: a row of little wheels, each showing one decimal digit
0 through 9. BCD is the digital version of that row. Every digit gets its own four-bit wheel, and you read the number digit by digit exactly as printed, rather than converting the whole thing out of one big binary value.One nibble per digit (the 8421 code)
Each decimal digit is stored in one nibble (4 bits) using the ordinary place values
8, 4, 2, 1, which is why plain BCD is also called 8421 code. The digit 0 is 0000, the digit 9 is 1001, and you read a nibble by adding the weights of its 1 bits, just like binary. The catch is that a nibble can hold sixteen patterns but a decimal digit only needs ten:| decimal digit | BCD (8421) |
|---|---|
| 0 | 0000 |
| 1 | 0001 |
| 2 | 0010 |
| 3 | 0011 |
| 4 | 0100 |
| 5 | 0101 |
| 6 | 0110 |
| 7 | 0111 |
| 8 | 1000 |
| 9 | 1001 |
1010 (10) through 1111 (15) are not valid BCD: a correct BCD nibble never holds them.So decimal
59 in BCD is 0101 1001: the nibble 0101 is the 5 and 1001 is the 9. Compare that with pure binary, where 59 is 0011 1011, a single value with no separable digits. The same number, two very different bit patterns.The six wasted codes, and packed versus unpacked
Because only ten of every sixteen patterns are used, BCD throws away
1010 through 1111, six codes per nibble. That is its main cost: a byte in pure binary holds 0 to 255, but the same byte as two BCD digits holds only 0 to 99, wasting about a third of its capacity. How those digits are packed into bytes has two styles:- Packed BCD: two digits per byte, one in each nibble. The byte
0101 1001is the two digits59. This is the compact form, and the one used for BCD arithmetic. - Unpacked BCD: one digit per byte, in the low nibble, with the high nibble left
0000(or used for a sign or a character code). The digit9becomes the byte0000 1001. This wastes more space but is easy to convert to printable text.
Why BCD exists, and what it costs
BCD is chosen whenever staying *exactly* decimal matters. Money is the big one: a value like
0.10 dollars has no exact representation in binary fractions (it repeats forever, like 1/3 in decimal), so binary arithmetic can drift by tiny rounding errors, whereas BCD stores cents exactly. Displays are the other: a decoder can turn each BCD nibble straight into the segments of one digit, with no division to extract digits. The price you pay is the six wasted codes per nibble and, as the next section shows, arithmetic that needs a correction step.BCD addition and the +6 correction
Adding BCD digits starts with an ordinary binary adder, but a plain binary sum can land on one of the six invalid codes or carry wrongly, because the adder counts in sixteens while a decimal digit rolls over at ten. The fix is a simple rule: after the binary add, if the nibble result is greater than
9 or it produced a carry out of the nibble, **add 6 (0110)** to skip past the six unused codes. That correction both fixes the digit and generates the proper decimal carry into the next digit.- Add the two BCD digits (and any incoming carry) with a normal 4-bit binary adder.
- If the result is
9or less and there was no carry out, it is already valid BCD: done. - If the result is greater than
9or a carry came out of the nibble, add0110(6). The low nibble of that sum is the corrected digit, and a1carries into the next decimal digit.
Worked example,
5 + 8 = 13. As binary, 0101 + 1000 = 1101, which is 13, greater than 9, so the result is invalid BCD and we add 6:0101 + 1000 = 1101 (13 > 9)
→ 1101 + 0110 = 1 0011
→ carry 1, digit 0011
→ BCD 0001 0011 = "13"
The
+6 pushed the result past the six wasted codes, leaving the units digit 0011 (3) and carrying a 1 into the tens digit, so the answer reads 0001 0011, which is BCD for 13. Every BCD adder is a binary adder plus this conditional +6 corrector on each digit.Designing the correction detector on a K-map
The whole
+6 rule hinges on one test: is the 4-bit binary sum greater than 9? That test is itself a small logic function of the sum bits, and a Karnaugh map hands you the gates in two strokes. Label the adder's four sum bits S3 S2 S1 S0 (weights 8, 4, 2, 1). The detector output, call it GT9, is 1 for the six invalid codes 1010 through 1111 and 0 for the ten valid digits 0000 through 1001:| S3 | S2 | S1 | S0 | GT9 |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 0 | 1 | 0 |
| 0 | 0 | 1 | 0 | 0 |
| 0 | 0 | 1 | 1 | 0 |
| 0 | 1 | 0 | 0 | 0 |
| 0 | 1 | 0 | 1 | 0 |
| 0 | 1 | 1 | 0 | 0 |
| 0 | 1 | 1 | 1 | 0 |
| 1 | 0 | 0 | 0 | 0 |
| 1 | 0 | 0 | 1 | 0 |
| 1 | 0 | 1 | 0 | 1 |
| 1 | 0 | 1 | 1 | 1 |
| 1 | 1 | 0 | 0 | 1 |
| 1 | 1 | 0 | 1 | 1 |
| 1 | 1 | 1 | 0 | 1 |
| 1 | 1 | 1 | 1 | 1 |
GT9 is 1 only for the six invalid codes 1010 (10) through 1111 (15); the valid digits 0000 through 1001 (including 1000 = 8 and 1001 = 9) all give 0.Drop those
1s onto a four-variable K-map with S3 S2 choosing the row and S1 S0 choosing the column, both Gray-ordered 00, 01, 11, 10. The six 1s fall into two large rectangular blocks of four:- The whole
S3=1, S2=1row (1100, 1101, 1110, 1111) is a block of four. Its two changing bitsS1andS0cancel, leaving the termS3·S2. - The
2 x 2block whereS3=1andS1=1(1010, 1011, 1110, 1111) is another block of four. Its changing bitsS2andS0cancel, leavingS3·S1. - OR the two blocks. Every invalid code is covered and no valid digit is:
GT9 = S3·S2 + S3·S1.
GT9 = S3·S2 + S3·S1 = S3·(S2 + S1) (1 for 1010..1111, 0 for 0000..1001)
So the correction fires when
GT9 is true or the adder already carried out of the nibble. That one signal, C = Cout + S3·S2 + S3·S1, does double duty: it switches the +6 corrector on, and it is the decimal carry into the next digit's adder. Two AND gates and two OR gates turn a plain 4-bit adder into one decimal digit's worth of BCD adder.Binary to BCD, and driving a display
The very same six-code correction is how you turn a pure binary value into BCD digits, by the shift-and-add-3 method (also called *double dabble*). You shift the binary number left one bit at a time into a set of 4-bit BCD digit columns, and before each shift you add
3 to any column that is already 5 or more. Adding 3 to a digit and then doubling it (the shift) is exactly adding 6 after the doubling, since 2 * (d + 3) = 2d + 6, and a digit only doubles past 9 when it was 5 or more (2d >= 10 means d >= 5). So it is the identical >9 -> +6 rule, applied one step earlier. Once you have clean BCD digits, each one drives a seven-segment decoder, itself just a handful of K-map-minimized segment functions, to light the display.Worked shift-and-add-3: convert binary
11111 (decimal 31) with two BCD columns, tens and units. Shifting the bits in one at a time, the units column reaches 0111 (7) after three shifts. Since 7 >= 5, add 3 before the next shift, then continue; two corrections later the columns settle on tens 0011 (3) and units 0001 (1), so the BCD result is 0011 0001 = decimal 31. The corrections are what keep each column a legal 0 to 9 digit instead of running into the six invalid codes.Excess-3: a self-complementing alternative
Excess-3 codes each digit as its value plus 3, so
0 is 0011 and 9 is 1100. The payoff is that it is self-complementing: the 9's complement of a digit (what you need for decimal subtraction) is just the bitwise NOT of its code. Inverting 0011 (the code for 0) gives 1100, which is the code for 9, and 0 and 9 are 9's complements. That makes subtraction circuitry simpler, the reason Excess-3 was used in some early machines.| digit | 8421 BCD | Excess-3 |
|---|---|---|
| 0 | 0000 | 0011 |
| 1 | 0001 | 0100 |
| 4 | 0100 | 0111 |
| 5 | 0101 | 1000 |
| 8 | 1000 | 1011 |
| 9 | 1001 | 1100 |
0 (0011) inverts to 1100 (9); 4 (0111) inverts to 1000 (5).The single decimal digit below is a BCD nibble you can set by hand. Its four bits carry the weights
8, 4, 2, 1, and only the patterns 0000 through 1001 are legal BCD values.d3-d0 (weights 8, 4, 2, 1) and read the decimal digit they spell, 0 to 9. Open it in the lab and try to make 9 (1001); anything above that, like 1010, is an invalid BCD code. A BCD-to-7-segment decoder would turn each such nibble into the lit segments of a display digit.Common mistakes. BCD is not pure binary: the byte
0101 1001 is 59 read as BCD but 89 read as a plain binary number, so never mix the two readings. Three more traps: the codes 1010 through 1111 are invalid in BCD and a correct digit nibble never holds one; BCD addition needs the conditional +6 correction whenever a digit exceeds 9 or carries, since a bare binary add gives a wrong BCD result; and remember BCD wastes six of every sixteen codes, so it is less dense than binary (a byte holds 0-99, not 0-255).Try it
Add the BCD digits
7 and 6. Show the binary sum, decide whether the +6 correction is needed, and give the two-digit BCD result.Answer
7 + 6 = 13. As binary, 0111 + 0110 = 1101, which is 13, greater than 9, so the +6 correction is needed: 1101 + 0110 = 1 0011. That is a carry of 1 and a units nibble of 0011 (3), so the result is 0001 0011, which is BCD for 13.BCD is the trade you make when exact decimal beats raw density: it keeps money and on-screen digits precise and easy to display, and in return you accept wasted codes and a correction step in the adder. It is also a first taste of choosing an encoding to fit a job rather than to be compact, the same kind of choice behind Gray code. Next, codes that add bits on purpose to *catch* mistakes: error detection and correction.
Frequently asked
What is binary-coded decimal (BCD)?
BCD stores each decimal digit in its own group of four bits using the place values
8, 4, 2, 1, so 0 to 9 map to 0000 to 1001. A multi-digit number keeps its digits separate, for example decimal 59 is 0101 1001, rather than being packed into one binary value.Why use BCD instead of binary?
Because it stays exactly decimal. Money values like
0.10 have no exact binary-fraction representation and can drift with rounding, while BCD stores the digits precisely. BCD also feeds displays easily, since each nibble can be turned straight into one digit's segments by a decoder, with no need to divide a binary value into digits.What are the invalid BCD codes?
The six patterns
1010, 1011, 1100, 1101, 1110, and 1111 (decimal 10 to 15). A valid BCD nibble only ever holds 0000 through 1001, so those six codes are unused, which is why BCD wastes about a third of a byte's capacity (a byte holds 0-99 instead of 0-255).Why do you add 6 in BCD addition?
A binary adder counts in sixteens, but a decimal digit must roll over at ten. When a digit's binary sum exceeds
9 or carries out of the nibble, adding 6 (0110) skips the six unused codes, leaving the correct decimal digit and producing the proper carry into the next digit. For example 5 + 8 gives binary 1101, and 1101 + 0110 corrects it to 0001 0011, BCD for 13.What is the difference between packed and unpacked BCD?
Packed BCD stores two digits per byte, one in each nibble (the byte
0101 1001 is 59), and is the compact form used for arithmetic. Unpacked BCD stores one digit per byte in the low nibble, leaving the high nibble 0000 or using it for a sign, which wastes more space but is easy to turn into printable text.How do you build a BCD adder's +6 correction logic?
Detect when the 4-bit binary sum exceeds
9. On a Karnaugh map of the sum bits S3 S2 S1 S0, the six invalid codes 1010 through 1111 group into S3·S2 + S3·S1. OR that with the adder's carry-out to get one signal that both switches on the +6 corrector and carries into the next decimal digit.How do you convert a binary number to BCD?
Use shift-and-add-3, also called double dabble: shift the binary value left one bit at a time into 4-bit BCD digit columns, and before each shift add
3 to any column that is already 5 or more. Adding 3 before doubling equals adding 6 after (2 * (d + 3) = 2d + 6), so it is the same greater-than-9 correction applied one step earlier. When every bit has been shifted in, the columns hold the decimal digits.Every lesson here builds toward one thing: a working CPU, from the transistor up.
Open the free lab →Builds towardThe seven-segment display decoder