[plt-scheme] question about Scheme numbers
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
sbloch at adelphi.edu