{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE Trustworthy #-}
module Data.FloatCast
( floatToWord
, wordToFloat
, doubleToWord
, wordToDouble
)
where
import Data.Word ( Word32
, Word64
)
import Data.Array.ST ( newArray
, readArray
, MArray
, STUArray
)
import Data.Array.Unsafe ( castSTUArray )
import GHC.ST ( runST
, ST
)
import Data.Flat.Endian
floatToWord :: Float -> Word32
floatToWord x = runST (cast x)
{-# INLINE floatToWord #-}
doubleToWord :: Double -> Word64
doubleToWord x = fix64 $ runST (cast x)
{-# INLINE doubleToWord #-}
wordToFloat :: Word32 -> Float
wordToFloat x = runST (cast x)
{-# INLINE wordToFloat #-}
{-# INLINE wordToDouble #-}
wordToDouble :: Word64 -> Double
wordToDouble x = runST (cast $ fix64 x)
cast
:: (MArray (STUArray s) a (ST s), MArray (STUArray s) b (ST s)) => a -> ST s b
cast x = newArray (0 :: Int, 0) x >>= castSTUArray >>= flip readArray 0
{-# INLINE cast #-}