xorshift-2: src/Random/Xorshift.hs
-----------------------------------------------------------------------------
--
-- Module : Random.Xorshift
-- Copyright :
-- License : LGPL 2.0 or higher
--
-- Maintainer :
-- Stability :
-- Portability :
--
-- | Xorshift random generators. The generators are implemented according to
-- the paper <http://www.jstatsoft.org/v08/i14/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