` COMPUTE! ISSUE 9 / FEBRUARY 1981 / PAGE 46`

A BCD to Floating-Point Binary Routine

Marvin L. De Jong
Department of Mathematics-Physics
The School of the Ozarks
Pt. Lookout, MO 65726

Introduction

The principal purpose of this article is to provide the reader with a program that converts a BCD number (ASCII representation) with a decimal point and/or an exponent to a floating-point binary number. The floating-point binary number has a mantissa of 32 bits, an exponent byte consisting of a sign bit and seven magnitude bits, and a sign flag (one byte) for the mantissa. Positive and negative numbers whose magnitudes vary from 1.70141183*1038 to 1.46936795*10-39 and zero can be handled by this routine. In subsequent articles I hope to provide an output routine and a four-function arithmetic routine. The routine described here could be used in conjunction with the Am9511 Arithmetic Processing Unit1 to perform a large variety of arithmetic functions.

Floating-Point Notation

Integer arithmetic is relatively simple to do with the 6502. Consult the Bibliography for a number of sources of information on multiple-byte, signed number addition, subtraction, multiplication and division. Scanlon's book, in particular, has some valuable assembly language routines of this sort. However, additional problems arise when the decimal number has a fractional part, such as the "14159" in the number 3.14159. Also, integer arithmetic is not suitable for handling large numbers like 2.3*1015. The solution is to convert decimal numbers to floating-point binary numbers. A binary floating-point number consists of a mantissa with an implied binary point just to the left of the most-significant non-zero bit and an exponent (or characteristic) that contains the information about where the binary point must be moved to represent the number correctly. Readers who are familiar with scientific notation will understand this quickly. Scanlon's book has a good section on floating-point notation. We will merely illustrate what a decimal number becomes in floating point binary by referring you to Table 1. The dashed line over a sequence of digits means that they repeat. For examples, 1/3 = .33 and 1/11 = .09090 = .090 while a binary example is 1/1010 = .00011001100 = .0001100.

 Table 1. Decimal number to floating-point binary conversions. NUMBER BINARY NUMBER FLOATING POINT NOTATION MANTISSA EXPONENT 0 0 0 × 20 0 0 1 1 .1 × 21 1 1 2 10 .1 × 22 1 10 4 100 .1 × 23 1 11 1.5 1.1 .11 × 21 11 1 0.75 .11 .11 × 20 11 0 0.1 0.00011001100 .1100 × 2-3 1100 -11 31 11111 .11111 × 25 11111 101 32 100000 100000 1 110

A close examination of Table 1 yields some important conclusions. Unless a number is an integer power of two (2n where n is an integer), the mantissa required to correctly represent the number will require more bits as the numbers increase. Thus, the number 1 can be correctly represented with a one-bit mantissa, but the number 31 requires a five-bit mantissa. A n-bit mantissa can correctly represent a number as large as 2n - 1, but no larger. There is another problem associated with numbers like 0.1ten that become repeating numbers in binary. It should be clear that no mantissa with a finite number of bits can represent 0.1 exactly. The fact that computers use a finite number of bits to represent numbers like 0.1 can be illustrated by using BASIC to add 0.1 to a sum and print the answer repeatedly. Starting with a sum of zero, we obtained an answer of 3.6 after 36 times through the loop, but the next answer is 3.69999999 which is clearly incorrect. The error incurred by using a finite number of bits, to represent a number that requires more than that number of bits to correctly represent it, is called roundoff error.

How many bits should be used for the mantissa? Clearly it should be an integer number of bytes for ease in programming. Some computers have software packages that use a 24 bit mantissa. The largest number that can be represented by 24 bits is 224 -1 = 16777215. This represents about seven decimal digits, giving about six digit accuracy after several calculations. With my salary there is no trouble with six digit accuracy, but many financial calculations require accuracy to the nearest cent, and six digits are frequently not enough. If we choose 32 bits for our mantissa size we get a little more than nine digits (4.3 × 109). This is the mantissa size used in several versions of Microsoft BASIC, and it is the size chosen here. The propagation of round-off errors through the calculations normally gives about eight digit accuracy. It is generally true that the roundoff errors accumulate as the number of calculations to find a specific result increases, but this is a subject beyond the scope of this article.

How big should the exponent be? If we choose to represent the binary exponent with one byte then we will have seven bits to represent the exponent (one sign bit and seven magnitude bits). The largest exponent is then +127. If all the bits in the mantissa are ones, then the largest number that can be represented is (1/2 + 1/4 + 1/8 + 1/16 + .... + 1/232)*2127, which is approximately 1.70141183*1038. The smallest exponent is -128. The smallest positive number that the mantissa can be is 1/2, thus the smallest positive number that can be represented is 2-129 which is approximately 1.46936795*10-39. Of course, if we chose to use two bytes for the exponent then much larger and smaller exponents could be accommodated, but for most calculations by earth people, a range of 10-39 to 1038 will do quite nicely. Remember that if you try to enter a number whose absolute value is outside of the range just given (except for zero) you will obtain erroneous results. No overflow or underflow messages are given when entering numbers with this routine.

One more note before turning to the program. The mantissa is said to be normalized when it is shifted so that the most-significant bit is one, and the binary point is assumed to be to the left of the most-significant bit. The only exception to this is the number zero which is represented by zeros in both the mantissa and the exponent. Although you are free to assume the binary point is some other place in the mantissa, it is conventional to keep it to the left of the mantissa, as illustrated in Table 1.

The Program To Float A Number

The program in Listing 1, written in the form of a subroutine, together with the other subroutines given in the listings, will accept numbers represented by ASCII from an input device and convert the numbers into their floating point representation. A typical entry might be + 12.3456789E + 24 or -.123456789E-30. The plus sign is optional since the computer simply disregards it. Up to 12 significant digits may be entered, although the least-significant three will soon be disregarded, leaving approximately 9 decimal digits (32 binary digits). At the completion of the routine, the floating-point representation will be found in locations \$0001, \$0002, \$0003, \$0004 (mantissa), \$0005 (exponent) and location \$0007 contains the sign of the mantissa. The sign byte is \$FF if the number is negative, otherwise it is \$00. Note that the accumulator (locations \$0001-\$0004) has not been complemented in the case of a minus number. Forming the twos complement may be done, when required, by the arithmetic routines. If a format compatible with the Am9511 Arithmetic Processing Unit is required, simply drop the least-significant byte of the mantissa (\$0004), put the sign (set the bit for a minus, clear it for a plus) in bit seven of the exponent (\$0005) and shift the sign of the exponent from bit seven to bit six, making sure to keep the rest of the exponent intact. Table 2 gives a summary of the important memory locations.

 Table 2. Memory assignments for the BCD to floating-point binary routine. \$0000 = OVFLO; overflow byte for the accumulator when it is shifted left or multiplied by ten. \$0001 = MSB; most-significant byte of the accumulator. \$0002 = NMSB; next-most-significant byte of the accumulator. \$0003 = NLSB; next-least-significant byte of the accumulator. \$0004 = LSB; least-significant byte of the accumulator. \$0005 = BEXP; contains the binary exponent, bit seven is the sign bit. \$0006 = CHAR; used to store the character input from the keyboard. \$0007 = MFLAG; set to \$FF when a minus sign is entered. \$0008 = DPFLAG; decimal point flag, set when decimal point is entered. \$000A = ESIGN; set to \$FF when a minus sign is entered for the exponent. \$000B = TEMP; temporary storage location. \$000C = EVAL; value of the decimal exponent entered after the "E." \$0017 = DEXP; current value of the decimal exponent.

After clearing all of the memory locations that will be used by routine, the program in Listing 1 jumps to a subroutine at \$0F9B. Most users will not want to call this subroutine, since it merely serves to clear the AIM 65 display. Subroutine INPUT, called next, must be supplied by the user. It must get a BCD digit represented in ASCII code from some input device, store it in CHAR at \$0006, and return to the calling program with the ASCII character in the 6502's accumulator. The necessary subroutines for the AIM 65 are given in Listing 4. They are given in the "K" disassembly format with no comments since they have previously been described by De Jong2. Our subroutines input the number on the keyboard and echo the number on the printer and the display.

The algorithm for the conversion routine was obtained from an article by Hashizume3. If you are interested in more details regarding floating-point arithmetic routines, please consult his fine article. A flow chart of the routine in Listing 1 is given in Figure 1. The flow chart and the program comments should be sufficient explanation. Basically it works by converting the number, as it is being entered, to binary and multiplying by ten, in binary of course. Later, if and when the exponent is entered, the number is either multiplied or divided by ten, in binary, to get a normalized mantissa and an exponent representing a power of two rather than a power often. Each time a multiplication or division by ten occurs the mantissa is renormalized and rounded upward if the most-significant discarded bit is one. Each normalization adjusts the binary exponent. When the decimal exponent finally reaches zero no more multiplications or divisions are necessary since 100 = 1. To maintain 32-bit precision, an extra byte, called OVFLO, is used in the accumulator for all *10 and /10 operations.

REFERENCES

1. De Jong, Marvin L., "Interfacing the Am9511 Arithmetic Processing Unit," COMPUTE II. (in press).

2. De Jong, Marvin L., "An AIM 65 Notepad," MICRO, No. 16, Sept. 1979, p. 11.

3. Hashizume, Burt, "Floating Point Arithmetic," BYTE, V 2, No. 11, Nov. 1977, p. 76.

BIBLIOGRAPHY

1. Programming and Interfacing the 6502, With Experiments, Marvin L. De Jong, Howard W. Sams & Co., Indianapolis, 1980.

2. 6502 Assembly Language Programming, Lance A. Leventhal, Osborne/McGraw-Hill, Berkeley, 1979.

3. 6502 Software Design, Leo J. Scanlon, Howard W. Sams & Co., Indianapolis, 1980. 