Converting IEEE 754 floating point in Haskell Word32/64 to and from Haskell Float/Double

前端 未结 4 737
情书的邮戳
情书的邮戳 2020-12-14 05:54

Question

In Haskell, the base libraries and Hackage packages provide several means of converting binary IEEE-754 floating point data to and from the l

4条回答
  •  太阳男子
    2020-12-14 06:44

    Simon Marlow mentions another approach in GHC bug 2209 (also linked to from Bryan O'Sullivan's answer)

    You can achieve the desired effect using castSTUArray, incidentally (this is the way we do it in GHC).

    I've used this option in some of my libraries in order to avoid the unsafePerformIO required for the FFI marshalling method.

    {-# LANGUAGE FlexibleContexts #-}
    
    import Data.Word (Word32, Word64)
    import Data.Array.ST (newArray, castSTUArray, readArray, MArray, STUArray)
    import GHC.ST (runST, ST)
    
    wordToFloat :: Word32 -> Float
    wordToFloat x = runST (cast x)
    
    floatToWord :: Float -> Word32
    floatToWord x = runST (cast x)
    
    wordToDouble :: Word64 -> Double
    wordToDouble x = runST (cast x)
    
    doubleToWord :: Double -> Word64
    doubleToWord x = runST (cast x)
    
    {-# INLINE cast #-}
    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
    

    I inlined the cast function because doing so causes GHC to generate much tighter core. After inlining, wordToFloat is translated to a call to runSTRep and three primops (newByteArray#, writeWord32Array#, readFloatArray#).

    I'm not sure what performance is like compared to the FFI marshalling method, but just for fun I compared the core generated by both options.

    Doing FFI marshalling is a fair bit more complicated in this regard. It calls unsafeDupablePerformIO and 7 primops (noDuplicate#, newAlignedPinnedByteArray#, unsafeFreezeByteArray#, byteArrayContents#, writeWord32OffAddr#, readFloatOffAddr#, touch#).

    I've only just started learning how to analyse core, perhaps someone with more experience can comment on the cost of these operations?

提交回复
热议问题