From: torvalds@klaava.Helsinki.FI (Linus Torvalds)
Subject: Re: Floating point: printf "%g" bug?
Organization: University of Helsinki
Date: Tue, 22 Dec 1992 20:24:24 GMT

In article <1992Dec22.130028.27444@csx.cciw.ca> hcp@csx.cciw.ca (H.C. Pulley) writes:
>
>I think the problem is just that double precision floating point IEEE format 
>is not significant to the number of digits you are trying to display.  If you
>try this with float instead of double you should see the same thing or worse

True in itself, although doubles (and even floats) certainly can hold
the exact representations of integers in the range 38-60, which the
example was about.  So the problem does seem to be the conversion
routines to ascii: they could be coded to handle these kinds of cases
better.  Perl seems to be very picky about these things in the tests,
even though it normally isn't a problem. 

>(this used to happen a lot in FORTRAN with different machines having very 
>different doubleprecision in the mainframe days - CDC Cybers have 128 bit 
>doubles, and you wonder why your answer is not the same as the guy using the 
>VAX).

More bits in fp certainly helps, but so does some careful coding.  The
problem is that writing the conversion routines correctly is a major
headache that very seldom is seen in practice: guaranteeing that exact
values get converted correctly while giving reasonable conversions for
things that cannot be expressed exactly in double format can be really
ugly.  It's possible, but you must never use divide-by-ten etc things
that are the "natural" way to do these things.  It gets worse if the
soft-float routines in use aren't exact (don't know about the Coherent
floating point calcs, but the original linux fpu emulator I wrote didn't
care about last-bit-correctness, so people saw a lot of these kinds of
things). 

The simplest (and naively obvious) way to do conversions from float ->
ascii is to convert the mantissa as a integer value, and then do a
suitable number of divide-by-two or multiply-by-two's on the resultant
bcd representation depending on the exponent.  This also guarantees
exact values - you're working on integers all the time (and *2 and /2
are easy to do exactly on bcd, at least until you decide that you don't
want more than about 20 digits..)

The problem with the above is that it doesn't work too well when the
exponent is big (negative of positive).  But those cases are also the
cases where the value is unlikely to actually be exact (it might be, but
nobody generally cares any more), so you can use a faster routine for
those cases, dividing/multiplying by powers of ten etc, and accept that
you no longer get a exact ascii representation of the value stored in
the floating point variable.

So it's certainly possible to make a routine that converts things that
can be represented exactly (small integers, powers of two like 0.125
etc) well, while doing reasonable work for other values.  It's just
generally easier to cut a few corners, and accept rounding errors in the
last digits in a few cases.  After all, you should never expect more
than 10 digits of accuracy of doubles anyway, even if 48 bits of
mantissa should theoretically give 14+ digits. 

		Linus