----------------------------------------------------------------------------- -- -- Module : Random.Xorshift -- Copyright : -- License : LGPL 2.0 or higher -- -- Maintainer : -- Stability : -- Portability : -- -- | Xorshift random generators. The generators are implemented according to -- the paper by George Marsaglia. -- You can use the 'RandomGen' instances to generate random numbers easily. -- This module only exports the Random generator that matches your word size, -- if you want to use a specific length, try "Random.Xorshift.Int32" and -- "Random.Xorshift.Int64" instead. ----------------------------------------------------------------------------- {-# LANGUAGE GeneralizedNewtypeDeriving, CPP #-} module Random.Xorshift ( Xorshift, newXorshift, makeXorshift, module System.Random ) where import System.Random import Data.Time -- Use the C-header file to generate a platform depend Xorshift type -- This is handy as I can use the __Xorshift macro as a data-constructor. #include "MachDeps.h" #if WORD_SIZE_IN_BITS == 32 #define __Xorshift Xorshift32 import Random.Xorshift.Int32 import Random.Xorshift.Int64 () #else #define __Xorshift Xorshift64 import Random.Xorshift.Int32 () import Random.Xorshift.Int64 #endif -- | Generates a new Xorshift from the current time. This is either a synonym -- for 'newXorshift32' or 'newXorshift64'. newXorshift :: IO Xorshift newXorshift = getRandomValue >>= return . makeXorshift -- | Generate a new 'Xorshift' generator, regardless of whatever it's bytesize -- is on your platform. makeXorshift :: Integral a => a -> Xorshift makeXorshift = __Xorshift . fromIntegral -- | The type Xorshift is a wrapper around either Xorshift32 or Xorshift64, -- depending on the bit size of your system. The idea behind this is, that -- you may want to use this package as an uncomplicated, fast random -- generator, but repeated conversion between different word sizes are an -- absolute performance killer. -- -- Thus, if you don't really care about the period of your random generator or -- how long the result is, use the 'Xorshift' synonym, whenever possible. type Xorshift = __Xorshift -- Generates a random value from current time. We try to archieve a good result -- by summing all information of time. getRandomValue :: IO Integer getRandomValue = do UTCTime (ModifiedJulianDay day) time <- getCurrentTime let picosecs = truncate $ toRational time * 10^(12 :: Int) dayInPs = day * 86400 * 10^(12 :: Int) return $! picosecs + dayInPs