# [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