Random instance for Double can generate values out of requested range
There appears to be an off-by-one error in randomIvalDouble, causing it to return values outside the requested range one time out of every few billion (exact frequency depending on the bounds of Int):
Prelude Control.Monad System.Random> (filter (<= 0) . randomRs (0,1)) `fmap` newStdGen :: IO [Double]
Loading package random-1.0.0.2 ... linking ... done.
[-1.1641532182693481e-10,-1.1641532182693481e-10^CInterrupted.
The problem appears to arise because int32Range does not represent the number of possible Int32's returned by the call to randomIvalInteger. Changing the division by int32Range in the definition of scaled_x to division by (int32Range + 1) should fix it. Attached is a darcs patch implementing this change. I don't actually know whether the resulting code reflects the intent of the interface, however. This version will produce the lower bound but not the upper bound.
Additionally, with or without the attached patch the basic structure of the scaling (adding a scaled Int32 to the midpoint of the range) does not play well with floating-point math in the first place: for example, randomR (exp 1, pi :: Double) can return a value one ULP less than 'exp 1'. This could probably be avoided by sampling a Word32 instead of an Int32 and adding the corresponding fraction of the range size to the lower bound.
Trac metadata
Trac field | Value |
---|---|
Version | 6.12.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | libraries/random |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |