On 03-Feb-2000, Tom Pledger <[EMAIL PROTECTED]> wrote:
>     import Random
> 
>     instance Random Ordering where
> 
>         random = randomR (minBound, maxBound)
> 
>         randomR (lo, hi) gen | lo <= hi =
>             let guaranteed   = 2^30
>                 loInt        = fromEnum lo
>                 hiInt        = fromEnum hi
>                 modulus      = hiInt - loInt + 1
>                 firstUseless = modulus * (guaranteed `div` modulus)
>                 rr g =
>                     let (i, g') = next g
>                         j       = i `mod` guaranteed
>                     in  if j < firstUseless then (j, g') else rr g'
>                 (raw, gen') = rr gen
>             in  (toEnum (loInt + raw `mod` modulus), gen')

I don't think that is guaranteed to work.  I think you are assuming
that `j' is uniformly distributed in the range 0..(2^30-1).
But this is only true if the range of the numbers returned
by `next' (i.e. the range of `Int') is a power of two.
The Haskell report hints at this, saying that the range you
get is "at least 30 bits", but I this could easily
be interpreted as just requiring the range to be >= 2^30,
without requiring it to be a power of 2.
If it is not a power of 2, then the distribution of
`j' will be skewed.

The code that I posted doesn't make that assumption.

I think your code also has a problem with assuming
that 2^30 will fit into an `Int'.  My code uses
`Integer' to avoid that.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger [EMAIL PROTECTED]        |     -- the last words of T. S. Garp.

Reply via email to