Harnon wrote:Sorry. (coerce .2 'double-float) produces

0.20000000298023224d0

(* .2 1d0) produces 0.20000000298023224d0

(* .2d0 .1d0) produces

0.020000000000000004d0

I think I will just stick to the float version of the c library. Thanks for the explanation!

Huh, strange that I completely missed your typo earlier, reading it as the above behavior (as you've corrected it)

This behavior is the expected one, as noted.

(and double-floats can store all single-floats without loss)

Is not particularly useful in this actual situation. The issue isn't whether or not you can represent 2/10 in both representations, but how you choose to map the smaller representation to the larger one, which obviously cannot be done bijectively. In this context there is nothing special about "0.2d0" compared to "0.20000000298023224d0", they both map to 0.2 in single precision.

All you can really hope for is consistency, which you have:

- Code: Select all
`CL-USER> (float .2 1d0)`

0.20000000298023224d0

CL-USER> (float (float .2 1d0) 1.0)

0.2

CL-USER> (float .2d0 1.0)

0.2

This is worth a read on the subject if you want to see some of the details:

What Every Computer Scientist Should Know About Floating-Point Arithmetic