module Data.Random.Internal.Words where
import Data.Bits
import Data.Word
import Foreign.Marshal (allocaBytes)
import Foreign.Ptr (castPtr)
import Foreign.Storable (peek, pokeByteOff)
import System.IO.Unsafe (unsafePerformIO)
{-# INLINE buildWord16 #-}
buildWord16 :: Word8 -> Word8 -> Word16
buildWord16 b0 b1
= unsafePerformIO . allocaBytes 2 $ \p -> do
pokeByteOff p 0 b0
pokeByteOff p 1 b1
peek (castPtr p)
{-# INLINE buildWord32 #-}
buildWord32 :: Word8 -> Word8 -> Word8 -> Word8 -> Word32
buildWord32 b0 b1 b2 b3
= unsafePerformIO . allocaBytes 4 $ \p -> do
pokeByteOff p 0 b0
pokeByteOff p 1 b1
pokeByteOff p 2 b2
pokeByteOff p 3 b3
peek (castPtr p)
{-# INLINE buildWord32' #-}
buildWord32' :: Word16 -> Word16 -> Word32
buildWord32' w0 w1
= unsafePerformIO . allocaBytes 4 $ \p -> do
pokeByteOff p 0 w0
pokeByteOff p 2 w1
peek (castPtr p)
{-# INLINE buildWord64 #-}
buildWord64 :: Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word64
buildWord64 b0 b1 b2 b3 b4 b5 b6 b7
= unsafePerformIO . allocaBytes 8 $ \p -> do
pokeByteOff p 0 b0
pokeByteOff p 1 b1
pokeByteOff p 2 b2
pokeByteOff p 3 b3
pokeByteOff p 4 b4
pokeByteOff p 5 b5
pokeByteOff p 6 b6
pokeByteOff p 7 b7
peek (castPtr p)
{-# INLINE buildWord64' #-}
buildWord64' :: Word16 -> Word16 -> Word16 -> Word16 -> Word64
buildWord64' w0 w1 w2 w3
= unsafePerformIO . allocaBytes 8 $ \p -> do
pokeByteOff p 0 w0
pokeByteOff p 2 w1
pokeByteOff p 4 w2
pokeByteOff p 6 w3
peek (castPtr p)
{-# INLINE buildWord64'' #-}
buildWord64'' :: Word32 -> Word32 -> Word64
buildWord64'' w0 w1
= unsafePerformIO . allocaBytes 8 $ \p -> do
pokeByteOff p 0 w0
pokeByteOff p 4 w1
peek (castPtr p)
{-# INLINE word32ToFloat #-}
word32ToFloat :: Word32 -> Float
word32ToFloat x = (encodeFloat $! toInteger (x .&. 0x007fffff )) $ (-23)
{-# INLINE word32ToFloatWithExcess #-}
word32ToFloatWithExcess :: Word32 -> (Float, Word32)
word32ToFloatWithExcess x = (word32ToFloat x, x `shiftR` 23)
{-# INLINE wordToFloat #-}
wordToFloat :: Word64 -> Float
wordToFloat x = (encodeFloat $! toInteger (x .&. 0x007fffff )) $ (-23)
{-# INLINE wordToFloatWithExcess #-}
wordToFloatWithExcess :: Word64 -> (Float, Word64)
wordToFloatWithExcess x = (wordToFloat x, x `shiftR` 23)
{-# INLINE wordToDouble #-}
wordToDouble :: Word64 -> Double
wordToDouble x = (encodeFloat $! toInteger (x .&. 0x000fffffffffffff )) $ (-52)
{-# INLINE word32ToDouble #-}
word32ToDouble :: Word32 -> Double
word32ToDouble x = (encodeFloat $! toInteger x) $ (-32)
{-# INLINE wordToDoubleWithExcess #-}
wordToDoubleWithExcess :: Word64 -> (Double, Word64)
wordToDoubleWithExcess x = (wordToDouble x, x `shiftR` 52)