[commit: packages/random] new_api: Intermediate checkin. Fixed one bug with the order of type conversion/shifting. Right now trying to fix randomIvalBits behavior on (signed) Ints. (7f44303)
git at git.haskell.org
git at git.haskell.org
Thu Mar 19 15:43:55 UTC 2015
Repository : ssh://git@git.haskell.org/random
On branch : new_api
Link : http://git.haskell.org/packages/random.git/commitdiff/7f44303fc009b282f940b986ab93feaaaba31489
>---------------------------------------------------------------
commit 7f44303fc009b282f940b986ab93feaaaba31489
Author: Ryan Newton <rrnewton at gmail.com>
Date: Mon Jun 27 13:05:25 2011 -0400
Intermediate checkin. Fixed one bug with the order of type conversion/shifting. Right now trying to fix randomIvalBits behavior on (signed) Ints.
>---------------------------------------------------------------
7f44303fc009b282f940b986ab93feaaaba31489
DEVLOG.md | 1 +
System/Random.hs | 33 ++++++++++++++++++++++++---------
2 files changed, 25 insertions(+), 9 deletions(-)
diff --git a/DEVLOG.md b/DEVLOG.md
index db1d12f..b482f1f 100644
--- a/DEVLOG.md
+++ b/DEVLOG.md
@@ -201,3 +201,4 @@ randomIvalBits uses a very inefficient bitScanReverse which can be
improved. And in spite of that it didn't slow down TOO much. Also,
randomIvalBits can fix the problems in tickets #5278 and #5280 having
to do with uniformity and assumptions about the generators.
+
diff --git a/System/Random.hs b/System/Random.hs
index eac2e1e..7a162ef 100644
--- a/System/Random.hs
+++ b/System/Random.hs
@@ -89,7 +89,14 @@ import Data.Char ( isSpace, chr, ord )
import System.IO.Unsafe ( unsafePerformIO )
import Data.IORef
import Numeric ( readDec )
+
+
+#define DEBUGRAND
+#ifdef DEBUGRAND
+import Numeric ( showIntAtBase )
+import Data.Char ( intToDigit )
import Debug.Trace
+#endif
-- The standard nhc98 implementation of Time.ClockTime does not match
-- the extended one expected in this module, so we lash-up a quick
@@ -425,9 +432,13 @@ randomBits desired gen =
if bits <= c
then loop g' (acc `shiftL` bits .|. fromIntegral x) (c - bits)
-- Otherwise we must make sure not to generate too many bits:
- else let shft = min bits c in
- (acc `shiftL` shft .|. (fromIntegral x `shiftR` fromIntegral (bits - shft)),
- g')
+ else
+ let shifted = fromIntegral (x `shiftR` (bits - c)) in
+#ifdef DEBUGRAND
+ trace (" Got random "++ showIntAtBase 16 intToDigit x "" ++
+ ", shifted "++ show (bits-c)++": " ++ show shifted) $
+#endif
+ (acc `shiftL` c .|. shifted, g')
in loop gen 0 desired
Nothing -> error "TODO: IMPLEMENT ME"
where
@@ -450,7 +461,10 @@ randomIvalBits :: (RandomGen g, Integral a, Bits a) => (a, a) -> g -> (a, g)
randomIvalBits (l,h) rng
| l > h = randomIvalBits (h,l) rng
| otherwise =
- -- trace ("Got pow2: "++ show pow2 ++ " range " ++ show range ++ " cutoff "++ show cutoff) $
+#ifdef DEBUGRAND
+ trace (" Got pow2: "++show pow2++" bounding "++show bounding++" maxbits "++show maxbits++
+ " range " ++ show range ++ " cutoff "++ show cutoff) $
+#endif
(l + fin_x, fin_rng)
where
(fin_x,fin_rng) =
@@ -462,14 +476,15 @@ randomIvalBits (l,h) rng
-- range is the number of distinct values we wish to generate:
-- If we are dealing with a signed type, range may be negative!
--- range = h - l + 1
- range = h - l
+ range = h - l + 1
maxbits = bitSize l
-- With randomBits we can only generate power-of-two ranges. We
-- need to find the smallest power-of-two that is bigger than range.
pow2 = findBoundingPow2 range
- bounding = 1 `shiftL` pow2
+ -- Bounding is the largest number we will generate with pow2 random bits:
+ -- bounding = (1 `shiftL` pow2) - 1 -- This could overflow!
+ bounding = complement 0 `shiftR` (maxbits - pow2)
cutoff = --if pow2 == maxbits
--then error "UNFINISHED"
--else
@@ -479,8 +494,8 @@ randomIvalBits (l,h) rng
-- results, but usually it should be much much less.
rollAndTrash g =
case randomBits pow2 g of
- (x,g') | x > cutoff -> rollAndTrash g'
- pair -> pair
+ (x,g') | x >= cutoff -> rollAndTrash g'
+ pair -> pair
-- Find the smallest power of two greater than or equal to the given number.
-- findBoundingPow2 :: (Bits a, Ord a) => a -> Int
More information about the ghc-commits
mailing list