From: Tom Kramer
Subject: Re: Urgent Assitance Required ...
Date: 
Message-ID: <24452@cosmos.cme.nist.gov>
In article <······················@waikato.ac.nz>,
Martin Glanvill <···@waikato.ac.nz> wrote:

>I require *exact* conversion from a single-float to a double-float ;
>
> (coerce 0.3 'double-float) -> 0.3000001192092896d0
>
>What I require is 0.3 -> 0.3[00000000000]d0 (precisely).

There have been several followup replies, but no one has said
why it is not feasible to do exactly what is requested.

A reasonable system that reads single-float numbers should be able to
echo them back exactly as entered, as long as the number of decimal
places does not exceed what is representable with a single float. For
example, if the system reads "0.3" into a single float and then prints
the value, it should print as "0.3" (assuming unnecessary trailing
zeros are suppressed by the print routine). If the system reads
"2.99999", it should print the value "2.99999". If the system
reads something long, such as 2.9999999999999, it would have the
choice of printing 3.0 or 2.99..99 (to however many places a single
float is good for).

It should be feasible to implement the coerce function (from single
float to double float) by behaving as though the number were first
printed from the single float and then read into a double float.
If this were done, the result would be what has been requested.

I have never understood why standards about dealing with numbers in
computers do not require the behavior just described. My impression is
that coercion is done simply by copying the single-float into the
first half of the space for a double float, and just leaving whatever
bits are in the rest of the double float the way they happen to be.
This has always struck me as a poor way to do coercion. Why can't the
rest of the bits be set so that when the number is printed, it is
what the single float would have been followed by a bunch of zeros?

Can someone who has actually implemented coercion please comment on
this. It has been bugging me for years. Other useful commentary is
also welcome. Thanks.

Tom Kramer
······@cme.nist.gov

From: Barry Margolin
Subject: Re: Urgent Assitance Required ...
Date: 
Message-ID: <2mi1heINNms2@early-bird.think.com>
In article <·····@cosmos.cme.nist.gov> ······@cme.nist.gov (Tom Kramer) writes:
>This has always struck me as a poor way to do coercion. Why can't the
>rest of the bits be set so that when the number is printed, it is
>what the single float would have been followed by a bunch of zeros?

Because this is a much less efficient way to do coercion, and it's only
useful if you're coercing a number that was read in.  It also introduces
additional error into the computation, which makes numerical analysis of
the algorithms more complicated.  Why should coercion be based on the
decimal representation when all other computations are done using binary?

Programmers using floating point should understand their limitations.
-- 
Barry Margolin
System Manager, Thinking Machines Corp.

······@think.com          {uunet,harvard}!think!barmar
From: Bruce R. Miller
Subject: Re: Urgent Assitance Required ...
Date: 
Message-ID: <2973265132@ARTEMIS.cam.nist.gov>
In article <·····@cosmos.cme.nist.gov>, Tom Kramer writes:
> In article <······················@waikato.ac.nz>,
> Martin Glanvill <···@waikato.ac.nz> wrote:
> >I require *exact* conversion from a single-float to a double-float ;
> >
> > (coerce 0.3 'double-float) -> 0.3000001192092896d0
> >
> >What I require is 0.3 -> 0.3[00000000000]d0 (precisely).
> 
> There have been several followup replies, but no one has said
> why it is not feasible to do exactly what is requested.

Hi Tom!

Actually, I've been waiting for someone to state that, in fact, the
system _did_ do an exact single->double conversion! (more below)

> A reasonable system that reads single-float numbers should be able to
> echo them back exactly as entered, 

I've found that they usually do.

> It should be feasible to implement the coerce function (from single
> float to double float) by behaving as though the number were first
> printed from the single float and then read into a double float.
> If this were done, the result would be what has been requested.

The (coerce (rationalize x) 'double-float) that someone suggested does
this, at some cost. 

> I have never understood why standards about dealing with numbers in
> computers do not require the behavior just described. My impression is
> that coercion is done simply by copying the single-float into the
> first half of the space for a double float, and just leaving whatever
> bits are in the rest of the double float the way they happen to be.

I've heard that some systems in the past have done this, but this is not
what is happening here.  Some clues are given by Genera's describe
function:
(describe 0.3)
0.3 is a single-precision floating-point number.
  Sign 0, exponent 175, 23-bit fraction 06314632  (not including hidden bit)
  Its exact decimal value is 0.300000011920928955078125

The first time I saw this "exact decimal value", I was a bit perplexed.
Then it dawned on me.  

Notice that a floating point number is a rational number (ie. it is NOT
a (real) REAL!), say X = b/(2^r) where r depends on the radix and
exponent.  A finite-precision decimal printed representation is also a
rational X = d/(10^R) for some R.  Since  d = b*10^R/(2^r), and 2
divides 10, we can always find an R such that d is an integer.
Which means, that any floating point number can be printed exactly with
a finite number of decimal digits.

Now, on the one hand, the last bit(s) in the mantissa of a float are
usually considered to be uncertain, and a single float gives ~7 digits
`accuracy' (in computation). On the other hand, that last bit
corresponds to an arbitrarily long (but finite) fraction.  
So, that `exact decimal value' printed by Genera really _is_ the exact
value of the float.  But the digits starting from 119... are essentially
noise --- they are the ones rounded away by the print routine when it
gets to the last useful decimal digit.

If you convert this single to double by putting 0's, not arbitrary
garbage, into the extra bits of mantissa, you'd get exactly the value
that Martin got. 

> This has always struck me as a poor way to do coercion. Why can't the
> rest of the bits be set so that when the number is printed, it is
> what the single float would have been followed by a bunch of zeros?

You could certainly contrive to fill the bits with something other than
0's, but what would be better?  If X were obtained directly from input, then
your suggestion would make sense.  But if X were obtained from arbitrary
computation, the only way to know the `correct' fill bits would be to
repeat the entire computation in double precision.
Computing clever fill bits would be time consuming, and as likely to be a
less correct coercion than a more correct one.

> Can someone who has actually implemented coercion please comment on
> this. It has been bugging me for years. Other useful commentary is
> also welcome. Thanks.
> 
> Tom Kramer
> ······@cme.nist.gov