[plt-scheme] question about Scheme numbers
At 9:53 AM -0600 5/13/06, Richard Cleis wrote:
>(define (add-x-to-nearly-3 x)
> (+ x 2.9999999999999996))
>
>(map add-x-to-nearly-3
> '(-1000 -100 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1.0 2.0 3 4 5 10 100 1000))
>
>Results could depend a little on the computer:
>
>(-997.0
> -97.0
> -7.0
> -6.0
> -5.0
> -4.0
> -3.0000000000000004
> -2.0000000000000004
> -1.0000000000000004
> -4.440892098500626e-16
> 0.9999999999999996
> 1.9999999999999996
> 2.9999999999999996
> 3.9999999999999996
> 5.0
> 6.0
> 7.0
> 8.0
> 13.0
> 103.0
> 1003.0)
>
>The effect is only noticeable on results near zero (for reasons that
>others have given.)
On my computer, all of these came out exactly the way mathematics
would predict; I think DrScheme saw the "2.9999999999999996" and
treated it as the exact fraction 29999999999999996/10000000000000000.
I tried again with (sqr (sqrt 3)) and got the results Richard quotes.
However, I also took the example farther into LARGE magnitudes:
(define (add-x-to-nearly-3 x)
(+ x (sqr (sqrt 3))))
(map add-x-to-nearly-3
'(0 1.0 2.0 3 4 5 10 100 1000 10000 100000 1000000 10000000
100000000 1000000000 10000000000 100000000000 1000000000000
10000000000000 100000000000000 1000000000000000 10000000000000000
20000000000000000 40000000000000000 100000000000000000))
and got as results
(list
#i2.9999999999999996
#i3.9999999999999996
#i5.0
#i6.0
#i7.0
#i8.0
#i13.0
#i103.0
#i1003.0
#i10003.0
#i100003.0
#i1000003.0
#i10000003.0
#i100000003.0
#i1000000003.0
#i10000000003.0
#i100000000003.0
#i1000000000003.0
#i10000000000003.0
#i100000000000003.0
#i1000000000000003.0
#i10000000000000002.0
#i20000000000000004.0
#i4e+16
#i1e+17)
Notice that in the fourth-to-last example, the last bit of precision
in a floating-point number has a value of 2, so it rounded to the
nearest even number. In the third-to-last example, I doubled the
number being added to nearly 3, the last bit of precision has a value
of 4, and it rounded to the nearest multiple of 4. Doubling again,
the last bit of precision has a value of 8, so it rounded to the
nearest multiple of 8.
--
Stephen Bloch
sbloch at adelphi.edu