Bug in the scaling of randoms in "Haskel: The Craft of Functional Programming"

Dimitre Novatchev dnovatchev@yahoo.com
Sat, 4 May 2002 06:05:45 -0700 (PDT)


In his excellent book Simon Thompson defines scaling of the elements of
a sequence of random numbers from the interval [0, 65535] to an
interval [s,t] in the following way (top of page 368):

> scaleSequence :: Int -> Int -> [Int] -> [Int]
> scaleSequence s t
>   = map scale
>     where
>       scale n = n `div` denom + s
>       range   = t - s + 1
>       denom   = modulus `div` range

where modulus = 65536

However, the following expression:

> e4000 = (scaleSequence 1 966 ([65231] ++ [1..965]))!!0

evaluates to 974 -- clearly outside of the specified interval.


I'm using the following scaling function, the correctness of which I
believe can be proven:

> randScale :: Float -> Float -> Int -> Int
> randScale s t n = floor (rndScl ((t - s + 1)/ dintRange ) s n)
>    where    dintRange = fromInt (modulus - 1)


> rndScl :: Float -> Float -> Int -> Float
> rndScl a b n = a * fromInt n + b 


> scaleSequence2 :: Int -> Int -> [Int] -> [Int]
> scaleSequence2 s t
>   = map scale
>     where
>       scale n = randScale (fromInt s) (fromInt t) n



Could somebody please, provide a corrected definition that still uses
modulo arithmetics?

Cheers,
Dimitre Novatchev.



__________________________________________________
Do You Yahoo!?
Yahoo! Health - your guide to health and wellness
http://health.yahoo.com