[plt-scheme] question about Scheme numbers

From: Stephen Bloch (sbloch at adelphi.edu)
Date: Sun May 14 08:38:10 EDT 2006

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


Posted on the users mailing list.