Binary-coded decimal
In computing and electronic systems, binary-coded decimal is a class of binary encodings of decimal numbers where each digit is represented by a fixed number of bits, usually four or eight. Sometimes, special bit patterns are used for a sign or other indications.
In byte-oriented systems, the term unpacked BCD usually implies a full byte for each digit, whereas packed BCD typically encodes two digits within a single byte by taking advantage of the fact that four bits are enough to represent the range 0 to 9. The precise four-bit encoding, however, may vary for technical reasons.
The ten states representing a BCD digit are sometimes called tetrades while the unused, don't care-states are named pseudo-tetrads, pseudo-decimals, or pseudo-decimal digits.
BCD's main virtue, in comparison to binary positional systems, is its more accurate representation and rounding of decimal quantities, as well as its ease of conversion into conventional human-readable representations. Its principal drawbacks are a slight increase in the complexity of the circuits needed to implement basic arithmetic as well as slightly less dense storage.
BCD was used in many early decimal computers, and is implemented in the instruction set of machines such as the IBM System/360 series and its descendants, Digital Equipment Corporation's VAX, the Burroughs B1700, and the Motorola 68000-series processors.
BCD per se is not as widely used as in the past, and is unavailable or limited in newer instruction sets. However, decimal fixed-point and decimal floating-point formats are still important and continue to be used in financial, commercial, and industrial computing, where the subtle conversion and fractional rounding errors that are inherent in binary floating point formats cannot be tolerated.
Background
BCD takes advantage of the fact that any one decimal numeral can be represented by a four-bit pattern. An obvious way of encoding digits is Natural BCD, where each decimal digit is represented by its corresponding four-bit binary value, as shown in the following table. This is also called "8421" encoding.This scheme can also be referred to as Simple Binary-Coded Decimal or BCD 8421, and is the most common encoding. Others include the so-called "4221" and "7421" encoding – named after the weighting used for the bits – and "Excess-3". For example, the BCD digit 6, in 8421 notation, is in 4221, in 7421, while in Excess-3 it is .
The following table represents decimal digits from 0 to 9 in various BCD encoding systems. In the headers, the "
8421" indicates the weight of each bit. In the fifth column, two of the weights are negative. Both ASCII and EBCDIC character codes for the digits, which are examples of zoned BCD, are also shown.| Digit | BCD 8421 | Stibitz code or Excess-3 | Aiken-Code or BCD 2421 | BCD 84−2−1 | 8421 | ASCII 0000 8421 | EBCDIC 0000 8421 |
| 0 | 0000 | 0011 | 0000 | 0000 | 1010 | 0011 0000 | 1111 0000 |
| 1 | 0001 | 0100 | 0001 | 0111 | 0001 | 0011 0001 | 1111 0001 |
| 2 | 0010 | 0101 | 0010 | 0110 | 0010 | 0011 0010 | 1111 0010 |
| 3 | 0011 | 0110 | 0011 | 0101 | 0011 | 0011 0011 | 1111 0011 |
| 4 | 0100 | 0111 | 0100 | 0100 | 0100 | 0011 0100 | 1111 0100 |
| 5 | 0101 | 1000 | 1011 | 1011 | 0101 | 0011 0101 | 1111 0101 |
| 6 | 0110 | 1001 | 1100 | 1010 | 0110 | 0011 0110 | 1111 0110 |
| 7 | 0111 | 1010 | 1101 | 1001 | 0111 | 0011 0111 | 1111 0111 |
| 8 | 1000 | 1011 | 1110 | 1000 | 1000 | 0011 1000 | 1111 1000 |
| 9 | 1001 | 1100 | 1111 | 1111 | 1001 | 0011 1001 | 1111 1001 |
As most computers deal with data in 8-bit bytes, it is possible to use one of the following methods to encode a BCD number:
- Unpacked: Each decimal digit is encoded into one byte, with four bits representing the number and the remaining bits having no significance.
- Packed: Two decimal digits are encoded into a single byte, with one digit in the least significant nibble and the other numeral in the most significant nibble.
91 using unpacked BCD results in the following binary pattern of two bytes:Decimal: 9 1
Binary : 0000 1001 0000 0001
In packed BCD, the same number would fit into a single byte:
Decimal: 9 1
Binary : 1001 0001
Hence the numerical range for one unpacked BCD byte is zero through nine inclusive, whereas the range for one packed BCD byte is zero through ninety-nine inclusive.
To represent numbers larger than the range of a single byte any number of contiguous bytes may be used. For example, to represent the decimal number
12345 in packed BCD, using big-endian format, a program would encode as follows:Decimal: 0 1 2 3 4 5
Binary : 0000 0001 0010 0011 0100 0101
Here, the most significant nibble of the most significant byte has been encoded as zero, so the number is stored as
012345. Packed BCD is more efficient in storage usage than unpacked BCD; encoding the same number in unpacked format would consume twice the storage.Shifting and masking operations are used to pack or unpack a packed BCD digit. Other bitwise operations are used to convert a numeral to its equivalent bit pattern or reverse the process.
Packed BCD
Some computers whose words are multiples of an octet, for example contemporary IBM mainframe systems, support packed BCD numeric representations, in which each nibble represents either a decimal digit or a sign. Packed BCD has been in use since at least the 1960s and is implemented in all IBM mainframe hardware since then. Most implementations are big endian, i.e. with the more significant digit in the upper half of each byte, and with the leftmost byte containing the most significant digits of the packed decimal value. The lower nibble of the rightmost byte is usually used as the sign flag, although some unsigned representations lack a sign flag.As an example, a 4-byte value consists of 8 nibbles, wherein the upper 7 nibbles store the digits of a 7-digit decimal value, and the lowest nibble indicates the sign of the decimal integer value. Standard sign values are 1100 for positive and 1101 for negative. This convention comes from the zone field for EBCDIC characters and the signed overpunch representation.
Other allowed signs are 1010 and 1110 for positive and 1011 for negative. IBM System/360 processors will use the 1010 and 1011 signs if the A bit is set in the PSW, for the ASCII-8 standard that never passed. Most implementations also provide unsigned BCD values with a sign nibble of 1111. ILE RPG uses 1111 for positive and 1101 for negative. These match the EBCDIC zone for digits without a sign overpunch. In packed BCD, the number 127 is represented by 0001 0010 0111 1100 and −127 is represented by 0001 0010 0111 1101. Burroughs systems used 1101 for negative, and any other value is considered a positive sign value.
| Sign digit | BCD 8 4 2 1 | Sign | Notes |
| A | 1 0 1 0 | + | |
| B | 1 0 1 1 | − | |
| C | 1 1 0 0 | + | Preferred |
| D | 1 1 0 1 | − | Preferred |
| E | 1 1 1 0 | + | |
| F | 1 1 1 1 | + | Unsigned |
No matter how many bytes wide a word is, there is always an even number of nibbles because each byte has two of them. Therefore, a word of n bytes can contain up to −1 decimal digits, which is always an odd number of digits. A decimal number with d digits requires bytes of storage space.
For example, a 4-byte word can hold seven decimal digits plus a sign and can represent values ranging from ±9,999,999. Thus the number −1,234,567 is 7 digits wide and is encoded as:
0001 0010 0011 0100 0101 0110 0111 1101
1 2 3 4 5 6 7 −
Like character strings, the first byte of the packed decimal that with the most significant two digits is usually stored in the lowest address in memory, independent of the endianness of the machine.
In contrast, a 4-byte binary two's complement integer can represent values from −2,147,483,648 to +2,147,483,647.
While packed BCD does not make optimal use of storage, conversion to ASCII, EBCDIC, or the various encodings of Unicode is made trivial, as no arithmetic operations are required. The extra storage requirements are usually offset by the need for the accuracy and compatibility with calculator or hand calculation that fixed-point decimal arithmetic provides. Denser packings of BCD exist which avoid the storage penalty and also need no arithmetic operations for common conversions.
Packed BCD is supported in the COBOL programming language as the "COMPUTATIONAL-3" or "PACKED-DECIMAL" data type. It is supported in PL/I as "FIXED DECIMAL". Beside the IBM System/360 and later compatible mainframes, packed BCD is implemented in the native instruction set of the original VAX processors from Digital Equipment Corporation and some models of the SDS Sigma series mainframes, and is the native format for the Burroughs Medium Systems line of mainframes.
Ten's complement representations for negative numbers offer an alternative approach to encoding the sign of packed BCD numbers. In this case, positive numbers always have a most significant digit between 0 and 4, while negative numbers are represented by the 10's complement of the corresponding positive number.
As a result, this system allows for 32-bit packed BCD numbers to range from −50,000,000 to +49,999,999, and −1 is represented as 99999999.