我想將Haskell Float轉換爲包含標準IEEE格式的浮點數的32位十六進制表示形式的字符串。我似乎無法找到一個能爲我做到這一點的軟件包。有人知道嗎?Haskell中浮點數的十六進制表示
我注意到,GHC.Float提供了一個函數來將Float分解爲它的帶符號的基和指數(decodeFloat),但是它分別爲基和指數提供了一個14和8位的十六進制數,佔用了大於32位。這似乎沒有幫助。
如果有更簡單的方法可以做到這一點,我沒有看到,請讓我知道。
我想將Haskell Float轉換爲包含標準IEEE格式的浮點數的32位十六進制表示形式的字符串。我似乎無法找到一個能爲我做到這一點的軟件包。有人知道嗎?Haskell中浮點數的十六進制表示
我注意到,GHC.Float提供了一個函數來將Float分解爲它的帶符號的基和指數(decodeFloat),但是它分別爲基和指數提供了一個14和8位的十六進制數,佔用了大於32位。這似乎沒有幫助。
如果有更簡單的方法可以做到這一點,我沒有看到,請讓我知道。
Hackage上的float-ieee包怎麼樣? http://hackage.haskell.org/package/data-binary-ieee754
將打印表示通過該浮子上的32位IEEE754字符串值。
import Data.Binary.Put
import Data.Binary.IEEE754
import qualified Data.ByteString.Lazy.Char8 as S
main = do
let s = runPut $ putFloat32be pi
S.putStrLn s
我想你不小心解碼的Double
而不是Float
的。這就是爲什麼它似乎不適合。
float-ieee軟件包是純粹的Haskell-98,但CPU密集型。如果你要需要做很多次了,不介意被GHC具體,那麼你用這樣的代碼,它提取的Double
爲Word64
的IEEE表示:
import GHC.Prim
import GHC.Types
import GHC.Word
encodeIEEEDouble :: Double -> Word64
encodeIEEEDouble (D# x) = W64# (unsafeCoerce# x)
decodeIEEEDouble :: Word64 -> Double
decodeIEEEDouble (W64# x) = D# (unsafeCoerce# x)
你可以代碼對於Float
和Word32
類似的東西。
從技術上講,這也假定'雙'在IEEE格式的硬件中表示,但這可能是GHC運行的每個平臺的情況。您還需要了解與「Word64」的機器表示有關的排序問題。 – 2010-09-23 12:49:33
有幾種不同的方式可以做到這一點,這取決於你的口味。使用像唐提到的庫可能是最好的選擇,否則你可以嘗試一些沿着這些線:
doubleToBytes :: Double -> [Int]
doubleToBytes d
= runST (do
arr <- newArray_ ((0::Int),7)
writeArray arr 0 d
arr <- castDoubleToWord8Array arr
i0 <- readArray arr 0
i1 <- readArray arr 1
i2 <- readArray arr 2
i3 <- readArray arr 3
i4 <- readArray arr 4
i5 <- readArray arr 5
i6 <- readArray arr 6
i7 <- readArray arr 7
return (map fromIntegral [i0,i1,i2,i3,i4,i5,i6,i7])
)
-- | Store to array and read out individual bytes of array
dToStr :: Double -> String
dToStr d
= let bs = doubleToBytes d
hex d' = case showHex d' "" of
[] -> error "dToStr: too few hex digits for float"
[x] -> ['0',x]
[x,y] -> [x,y]
_ -> error "dToStr: too many hex digits for float"
str = map toUpper $ concat . fixEndian . (map hex) $ bs
in "0x" ++ str
-- | Create pointer to Double and cast pointer to Word64, then read out
dToStr2 :: Double -> IO String
dToStr2 f = do
fptr <- newStablePtr f
let pptr = castStablePtrToPtr fptr
let wptr = (castPtrToStablePtr pptr)::(StablePtr Word64)
w <- deRefStablePtr wptr
let s = showHex w ""
return ("0x" ++ (map toUpper s))
-- | Use GHC specific primitive operations
dToStr3 :: Double -> String
dToStr3 (D# f) = "0x" ++ (map toUpper $ showHex w "")
where w = W64# (unsafeCoerce# f)
三種不同的方式。最後是GHC具體。其他兩個可能與其他Haskell編譯器一起工作,但是對底層實現依賴性很小,很難保證。
在Haskell中漂浮只有4個字節(32位)?這似乎不足以給你一個14位數的尾數和一個8位指數。 – pavium 2010-02-16 00:12:47