2010-02-15 15 views
7

मैं एक हास्केल फ्लोट को स्ट्रिंग में परिवर्तित करना चाहता हूं जिसमें मानक आईईईई प्रारूप में फ्लोट के 32-बिट हेक्साडेसिमल प्रतिनिधित्व शामिल हैं। मुझे ऐसा पैकेज नहीं मिल रहा है जो मेरे लिए यह करेगा। क्या किसी को पता है?हास्केल में फ्लोट्स का हेक्स प्रतिनिधित्व

मैंने देखा है कि GHC.Float अपने हस्ताक्षर किए बेस प्रतिपादक (decodeFloat) में एक फ्लोट विघटित करने के लिए एक समारोह प्रदान करता है, लेकिन यह क्रमश: आधार और प्रतिपादक, के लिए एक 14- और 8 अंकों हेक्स नंबर प्रदान करता है, जो 32 बिट्स से ज्यादा लेता है। यह मदद नहीं प्रतीत होता है।

यदि ऐसा करने का कोई आसान तरीका है जो मैं नहीं देख रहा हूं, तो कृपया मुझे बताएं।

+0

हास्केल में केवल 4 बाइट्स (32 बिट्स) में तैरते हैं? यह आपको 14 अंकों की मंटिसा और 8-बिट एक्सपोनेंट देने के लिए पर्याप्त प्रतीत नहीं होता है। – pavium

उत्तर

4

हैकेज पर फ्लोट-यानी पैकेज के बारे में कैसे? 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 
+0

यह प्रिंट "पीआई" के रूप में "@I" है। क्या यह एक अलग हेक्स प्रतिनिधित्व है? – Jeremy

+0

यह हेक्स नहीं है। यह सिर्फ एक उपद्रव है। हेक्स में बाइटस्ट्रिंग मान मुद्रित करने के लिए आपको एक अलग लाइब्रेरी/फ़ंक्शन की आवश्यकता है। – sclv

1

मुझे लगता है कि अगर आप गलती से एक Double बजाय डीकोड एक Float की। यही कारण है कि यह फिट नहीं लग रहा है।

5

फ्लोट-यानी पैकेज शुद्ध हास्केल -98 है, लेकिन बहुत सीपीयू गहन है।

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) 

आप कोड कर सकते हैं: आप इस के लिए कई बार ऐसा करने के लिए, और कोई आपत्ति नहीं है GHC विशिष्ट होने की जरूरत करने जा रहे हैं, तो आप इस तरह कोड है, जिनमें से एक एक Word64 रूप Double आईईईई प्रतिनिधित्व अर्क का उपयोग Float और Word32 के लिए कुछ समान है।

+0

तकनीकी रूप से, यह भी मानता है कि आईईईई प्रारूप में हार्डवेयर में 'डबल' का प्रतिनिधित्व किया जाता है, लेकिन शायद यह संभव है कि जीएचसी चलने वाले प्रत्येक प्लेटफ़ॉर्म के लिए मामला हो। आपको 'वर्ड 64' के मशीन प्रतिनिधित्व के संबंध में एंडियननेस मुद्दों के बारे में भी जागरूक होने की आवश्यकता होगी। –

2

आपके स्वाद के आधार पर आप इसे कुछ अलग तरीके से कर सकते हैं। का उपयोग करते हुए डॉन की तरह एक पुस्तकालय का उल्लेख शायद सर्वोत्तम विकल्प है, अन्यथा आप इन की तर्ज पर कुछ कोशिश कर सकते हैं:

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) 

तीन अलग अलग तरीकों से। अंतिम जीएचसी विशिष्ट है। अन्य दो अन्य हास्केल कंपाइलर्स के साथ काम कर सकते हैं लेकिन अंतर्निहित कार्यान्वयन पर थोड़ा सा भरोसा कर सकते हैं ताकि गारंटी हो सके।

संबंधित मुद्दे