[plt-scheme] flonums question

From: David Brown (plt at davidb.org)
Date: Sat Jan 16 17:03:45 EST 2010

On Sat, Jan 16, 2010 at 09:50:15PM +0100, Jos Koot wrote:
>#lang scheme
>
>; I do not understand the difference between the following two:
>
>(let loop ((x 0))
> (let ((d (- 1.0 (+ 1.0 (expt 2 x)))))
>  (if (= d 0) x
>   ; d is an inexact real number.
>   ; well, all reals are inexact I think.
>   ; an exact real would have to be an exact ranional, is it not?
>   (loop (sub1 x))))) ; --> 54
>; flonum arithmetic I think.
>
>(let loop ((x 0))
> (let ((d (exact->inexact (- 1 (+ 1 (expt 2 x))))))
>  ; d is an inexact rational number.
>  (if (= d 0) x
>   (loop (sub1 x))))) ; --> -1075
>; where does this high though finite precision come from?

In the first case, you're computing the number of bits of magnitude in
a flonum.  In the second case, you're computing the closest you can
get to zero (basic you're determining the number of bits in the
exponent).

The first case reaches zero when the exponent has enough bits that
lowest bit in it's representation is larger than '1'.  The second case
reaches zero when the exponent is too large, and the number is
truncated to zero.  The first case, the error happens at the subtract,
and in the second case, it happens when that result is turned into a
flonum.

Different scheme implementation seem to give either -1075 or -1024,
which suggest different handling of denormal numbers.  (Chicken
returns -53, since it doesn't have exact numbers larger than a
fixnum).

It helps to print out 'd' before the if in each of the cases.

David


Posted on the users mailing list.