Floating point exactness & alternatives (summary)

William Bill Mayne mayne at VSSERV.SCRI.FSU.EDU
Fri Aug 10 01:13:47 AEST 1990


In article <168 at srchtec.UUCP> johnb at srchtec.UUCP (John Baldwin) writes:
>In article <1990Aug7.173030.2823 at zoo.toronto.edu> henry at zoo.toronto.edu (Henry Spencer) writes:
>>In article <713 at tetrauk.UUCP> rick at tetrauk.UUCP (Rick Jones) writes:
>>>  Auditors have this annoying view that accounts must balance to the
>>>penny, not 1 part in 10 to-the-something.  There is a good case for using some
>>>form of BCD representation, but there are many programming advantages in using
>>>the embedded numerical types of the language...
>>
I strongly agree both about BCD and using the embedded types (and operators)
of the language.

SUMMARY of my response:

Seeing the original poster's description of his problem it seems to me 
that what is really needed is not floating point numbers but fixed point 
numbers with a moderately large number of digits and scaling for decimal
point placement. The traditional approach would be to use BCD.
Although the kind of arithmetic support needed is possible
in C, and I describe the approach I'd take below, the point is well taken 
that it is more desirable to use the builtin operators, rather than
have to use explicit function calls for every operation. Thus the best
alternative is a language which provides either BCD or some other
mechanism to support arithmetic in the scale and precision needed. 
If using a language which already has the needed arithmetic features
is ruled out by considerations of hardware, cost, programmer skills,
or what ever the best solution may be to use C++. With operator
overloading once a class for BCD is provided programmers can use
C syntax for their applications. The rest of this article just expands
a little on this summary.

You could write your own routines in C to support BCD or something 
functionally equivalent. One relatively simple alternative would be using 
long integers (which I think would give enough significant digits) plus a 
signed short integer for decimal scaling. Then you would have some 
interesting problems with division and handling overflows and such, but no 
more than floating point implementers face. On a machine without hardware
support for either BCD or floating point I think this scheme of using binary
for the significant part but decimal exponents would be the most satifactory.

A number would be represented by a structure like this:
/* Please no flames if the syntax isn't exactly right,      */
/* I don't use this often and don't have a reference handy. */

typedef BCD
  struct
    {
    long digits;
    short exponent;
    }

This would be normalized so that for all nonzero values
digits%10!=0 and the value represented is digits * 10**exponent. 
Most of the arithmetic would be done in binary, but using a decimal
exponent part avoids the problems of representing values like
0.2, which is a repeating fraction in binary and gives accountants
so much heartburn.

Although solutions in C are possible and even interesting I would
suggest that C may not be the best language for this type of problem.
Instead, consider:

  (1) COBOL
  (2) PL/1
  (3) Turbo Pascal with the BCD option
  (4) C++
  (5) Rexx

COBOL and PL/1 both provide the kind of arithmetic support needed for
this problem, plus business oriented output formatting. Of the two PL/1
is a much better language. However, you may not have these available or
have programmers proficient in using them, especially if you are in a
microcomputer environment.

If you are using PCs you might look into Turbo Pascal. Support for BCD
is (or was the last time I looked) an extra cost option, but quite
reasonable. I haven't used it so I don't know how well it works.

With C++ you might still have to write you own routines to support BCD
(though I wouldn't be surprised if you could find a package somewhere).
A big advantage over doing the same thing in C would be that you could 
then overload the regular arithmetic operators to use the new format.
This would make coding and maintaining your appication much easier, and
is probably the most portable of the solutions suggested here (short of
using C, which as I said is really not well suited to this type of 
problem.) If performance is a problem and your hardware supports BCD
(which I think math coprocessors do) you should try to use it, even though
a small assembly language interface might to required to gain access
to it and of course portability would suffer.

Rexx is a fine interpreted language with support for arbitrary precision
arithmetic, using fixed point when possible and only going to floating
point when the exponents get too small or too large. You can control the
digits setting so this won't happen. It is available on PCs (Personal Rexx
from Mansfield (CT) software), IBM mainframes, amigas, and many unix
platforms (from /wrk/group). Performance and space might be a problem,
depending upon the demands of the application. Rexx stores all values as 
strings. Hence it doesn't take much advantage of hardware support for
arithmetic. Its main use is actually as macro language.

Good luck, and keep the newsgroup posted on your solutions. Thanks to the
original poster for the interesting summary. 



More information about the Comp.lang.c mailing list