Binary-Coded Decimal

In electronic control systems, binary-coded decimal (BCD) is a method for representing decimal numbers in which each decimal digit is represented by a sequence of binary digits. This makes it relatively easy for the system to convert the numeric representation for printing or display purposes, and speeds up decimal calculations. The main disadvantage is that representing decimal numbers in this way takes up more space in memory than using a more conventional binary representation. The circuitry required to carry out calculations also tends to be more complex. The decimal digits 0-9 are each represented using four bits. Additional bit combinations may be used to represent sign values (+ or -) or other values (e.g. overflow or error conditions). The table below shows the standard BCD encodings for the decimal digits 0-9. Note that values greater than 1001 (1010, 1011, 1100, 1101, 1110, or 1111) are not valid BCD decimal values.

 BCD Representation Decimal BCD Encoding 0 0000 1 0001 2 0010 3 0011 4 0100 5 0101 6 0110 7 0111 8 1000 9 1001

The BCD encoding for the number 123 would therefore be:

0001 0010 0011

As opposed to the normal binary representation:

1111011

Computers usually store data in blocks of 8 bits (called bytes). Two main methods of storing BCD digits are used. In the first method (called zoned BCD), each 4-bit BCD representation of a decimal digit is stored in the right-most four bits of a byte. The left-most four bits are all set to zero, or all set to one in systems such as mainframe computers that use Extended Binary Coded Decimal Interchange Code (EBCDIC), or to 0011 (in systems that use the American Standard Code for Information Interchange (ASCII). In the second form of representation, two BCD encoded decimal digits are stored in a single byte. Displaying a BCD-encoded number is relatively straightforward for hardware, because each of the numeric characters is mapped to a distinct bit pattern consisting of four binary digits. The control circuitry required to display each number is therefore relatively straightforward since no arithmetic conversion is required.

Another variation on BCD encoding called packed BCD uses each byte of a multi-byte word to store two BCD-encoded decimal digits except the lowest byte. In this byte, the upper four bits are used to store a BCD-encoded decimal digit, but the lowest four bits are used to store the sign value (most commonly 1100 for '+' and 1101 for '-'). A 32-bit word can thus hold a 7-digit signed decimal number using binary coded decimal encoding. The number -1,234,567 would therefore be represented as follows:

0001 0010 0011 0100 0101 0110 0111 1101

The same sign values can be used with zoned BCD to represent signed numbers. The left-most four bits of the least significant byte are used to represent the sign of the number. For an EBCDIC representation of -123, therefore, the binary pattern used would be as follows:

1111 0001 1111 0010 1101 0011

Unpacked BCD numbers can be added together in the same way that other binary numbers are added together, with the result being put into the appropriate binary format afterwards. If the result of adding two BCD numbers is greater than 910 (1001), however, the result will be invalid and must be corrected by adding 610 (0110). Take the example of adding 7 and 8:

0000 0111
+ 0000 1000
---------
= 0000 1111

The answer derived is OK for normal binary addition (11112 = 1510) but results in an invalid BCD representation. In order to rectify this, we need to add 6 (0110) to the result, as follows (note that the number being added must also be in the unpacked format):

0000 1111
+ 0000 0110
---------
= 0001 0101

We now have two BCD values represented, 1 and 5. This is the correct BCD representation of 15 (the correct result of adding 7 and 8). In order to correctly represent this number in the unpacked BCD format, however, we need to shift the left-most four bits of the answer into a higher-order byte, as shown below.

0000 0001 0000 0101 = 1510

Adding together groups of BCD values is trickier, but basically involves adding each set of BCD encoded values from right to left, and carrying the second digit to the next highest order byte (remembering of course to correct for invalid BCD results before doing so). The following example, in which we will add 97 to 48, illustrates the principle (note that the BCD-encoded values that will appear in the final encoding are highlighted at each stage):

Add the first set of values:

0000 0111
+ 0000 1000
---------
= 0000 1111

The result is an invalid BCD value, so add 0110:

0000 1111
+ 0000 0110
---------
= 0001 0101

Add the second set of values (plus the 1 carried from the first addition):

0000 1001
+ 0000 0100
+ 0000 0001
---------
= 0000 1110

This result of this addition is also an invalid BCD value, so add 0110:

0000 1110
+ 0000 0110
---------
= 0001 0100

The 1 will be carried into the next highest order byte. The overall result of the addition is shown below (note that the same method for addition can also be applied to packed BCD - just remember that each byte contains two BCD-encoded decimal digits rather than one).

0000 0001 0000 0100 0000 0101 = 14510

BCD subtraction

Binary subtraction can be carried out on both packed and unpacked BCD-encoded numbers in the same way that it can for numbers that use a standard binary representation. Note that, as with addition, subtraction can result in an invalid BCD value. It can also give an erroneous answer if the subtraction operation results in a borrow (from the next highest BCD-encoded value). If either of these situations occurs, an adjustment is needed to produce a correct result. For subtraction, we need to subtract 6 (0110) from the invalid or erroneous BCD value. Some examples will illustrate the point (we will use packed BCD values for the purposes of this exercise). First, a straightforward example that requires no corrections would be to subtract 12 from 37:

0011 0111
- 0001 0010
---------
= 0010 0101

For the next example, we will subtract 19 from 65:

0110 0101
- 0001 1001
---------
= 0100 1100

Since the right-most BCD value is invalid, we need to subtract 6 (0110):

0100 1100
- 0000 0110
---------
= 0100 0110

0100 0110 = 4610

For the final example we will subtract 18 from 41:

0100 0001
- 0001 1000
---------
= 0010 1001

Since we had to borrow from the left most BCD value when subtracting, the right most BCD value in the result is erroneous and we again need to subtract 6 (0110):

0010 1001
- 0000 0110
---------
= 0010 0011