[plt-scheme] question about Scheme numbers

From: Stephen Bloch (sbloch at adelphi.edu)
Date: Sat May 13 07:18:42 EDT 2006

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


Posted on the users mailing list.