From: Stephen Bloch (sbloch at adelphi.edu) Date: Sat May 13 07:18:42 EDT 2006 Previous message: [plt-scheme] question about Scheme numbers Next message: [plt-scheme] question about Scheme numbers Messages sorted by: [date] [thread] [subject] [author]

```Peter Horst wrote:
>Calculating the hypotenuse of a 30-60-90 right triangle I get:
>
>>  (hypo (sqrt 3) 1)
>2.0
>
>but
>
>>  (square (sqrt 3))
>2.9999999999999996
>
>How come?

Jens Axel Søgaard replied:
>  (sqrt 3) can not be represented exactly using floating point numbers,
>  so instead the result of (sqrt 3) is the closest representable number.
>  Squaring a number close to (sqrt 3) results in a number close to 3
>  namely 2.9999999999999996.

But that doesn't completely answer the question.
If (square (sqrt 3)) is NOT QUITE 3,
you might expect (sqrt (+ 1 (square (sqrt 3))))
to be NOT QUITE 2.  Why is it coming out 2?

There are actually two different phenomena going
on here.  First, floating-point numbers are
stored with a fixed number of (binary) places of
accuracy: if there are more digits in front of
the point, there are fewer after the point.  So
for example
>  (sqr (sqrt 3))
#i2.9999999999999996
>  (+ 1 (sqr (sqrt 3)))
#i3.9999999999999996
>  (+ 2 (sqr (sqrt 3)))
#i5.0
The last of these happens because the computation
produces something more than the next power of 2
(i.e. 4), so the floating-point representation
loses one bit off the low-significance end; the
computer rounds this to the nearest available
floating-point representation, and in this case
it happens to round up.

But that still doesn't explain the specific
example Peter found, in which he was only adding
1 rather than 2.  This time the answer is that,
mathematically, (sqrt (- x epsilon)) is much less
than epsilon away from (sqrt x); since epsilon
was already as small a difference as the
floating-point representation could show, again
the computer rounded the answer to the nearest
available floating-point representation, which
happened to be 2.0.
--
Stephen Bloch