home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.os.coherent
- Path: sparky!uunet!mcsun!news.funet.fi!hydra!klaava!torvalds
- From: torvalds@klaava.Helsinki.FI (Linus Torvalds)
- Subject: Re: Floating point: printf "%g" bug?
- Message-ID: <1992Dec22.202424.14996@klaava.Helsinki.FI>
- Organization: University of Helsinki
- References: <1992Dec21.123913.2881@philips.oz.au> <1992Dec22.130028.27444@csx.cciw.ca>
- Date: Tue, 22 Dec 1992 20:24:24 GMT
- Lines: 55
-
- 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
-