2012-01-23 14 views
9

मेरे पास एक फ़ाइल है जिसमें [Double] डेटा द्वारा क्रमबद्ध है। बाइनरी जो मैं सी के साथ पढ़ना चाहता हूं। यही है, मैं एक सी प्रोग्राम लिखना चाहता हूं जो उस डेटा को double[] के रूप में स्मृति में पढ़ता है। मैं डेटा फ़ाइल को deserialize करने के लिए एक हास्केल प्रोग्राम लिखने की योजना बना रहा हूं और फिर बाइनरी डेटा को एक नई, सरल फ़ाइल में लिखता हूं जिसे मैं सीधे सी में पढ़ सकता हूं, लेकिन मुझे यकीन नहीं है कि कच्चे बाइनरी डेटा को कैसे लिखना है (उदाहरण के लिए एक डबल के लिए 8 बाइट्स)।सी द्वारा पढ़ा जाने के लिए हास्केल के साथ बाइनरी डेटा लिखें?

उत्तर

3

Data.Binary का उपयोग Double या Float क्रमशः पोर्टेबिलिटी के लिए अच्छा नहीं है। Binary उदाहरण decodeFloat द्वारा प्राप्त फॉर्म में मूल्यों को क्रमबद्ध करते हैं, यानी एक मंटिसा और एक एक्सपोनेंट के रूप में। मंथिसा को Integer के रूप में क्रमबद्ध किया गया है। पार्सिंग जो असुविधाजनक है। जैसा कि पहले से ही एहर्ड द्वारा सुझाया गया है, उतना ही बेहतर है, जो कि वेरिएंट को आईईईई -754 प्रतिनिधित्व के बिट-पैटर्न के रूप में क्रमबद्ध करता है, जैसा कि cereal-ieee754 द्वारा दिया गया है - जैसा कि एहर्ड ने मुझे याद दिलाया है, जिसे विलय कर दिया गया है (फ्लोटिंग पॉइंट के बीच कुछ रूपांतरण घटाएं और शब्द प्रकार) cereal में - या पहले से ही उल्लेख किया गया data-binary-ieee754। एक और विकल्प उन्हें show के माध्यम से स्ट्रिंग के रूप में क्रमबद्ध कर रहा है। इसका कोई अंतहीनता समस्याओं से बचने का लाभ है।

+0

वैसे, अनाज-यानी 754 की कार्यक्षमता हाल ही में अनाज उचित में विलय कर दी गई थी। – ehird

+0

आह, धन्यवाद। मैं भूल गया। दुर्भाग्यवश 'वर्ड 64 <-> डबल' और' वर्ड 32 <-> फ़्लोट 'रूपांतरण हटा दिए गए थे, और वे एकमात्र चीजें हैं जिन्हें मुझे पैकेज में दिलचस्पी होगी;) –

+0

हाँ, यह अच्छा होगा अगर वे एक अलग पैकेज में विभाजित हो जाएं कि धारावाहिक पुस्तकालयों पर निर्भर हो सकता है। – ehird

8

आप data-binary-ieee754 पैकेज है, जो serialising की अनुमति देता है Float रों और उनके आईईईई प्रतिनिधित्व के रूप में Double रों साथ प्रयोजन के लिए Data.Binary का पुन: उपयोग कर सकते हैं। उदाहरण के लिए:

import Data.List 
import Data.Binary.Put 
import Data.Binary.IEEE754 
import Control.Monad 

putRawDoubles :: [Double] -> Put 
putRawDoubles xs = do 
    putWord64le $ genericLength xs 
    mapM_ putFloat64le xs 

यह अगर वहाँ डेटा-द्विआधारी-ieee754 में Double रों लिए putWord64host एक एनालॉग था अच्छा होगा, लेकिन मैं तो बस थोड़ा-endian साथ चला गया के बाद से वहाँ नहीं है। यदि आप अपने सी प्रोग्राम में रूपांतरण को स्पष्ट रूप से संभाले बिना अंतहीनता में पोर्टेबल बनना चाहते हैं, तो आप putWord64host . doubleToWord (doubleToWordData.Binary.IEEE754 से भी) का प्रयास कर सकते हैं। हालांकि मुझे लगता है कि पूर्णांक अंतराल कुछ प्लेटफार्मों पर फ्लोटिंग-पॉइंट एंडियननेस से अलग है ...

संयोग से, मैं आपके नियमित क्रमिकरण के लिए भी इस तरह के प्रारूप का उपयोग करने का सुझाव दूंगा; आईईईई फ्लोट सार्वभौमिक हैं, और बाइनरी का डिफ़ॉल्ट फ़्लोटिंग-पॉइंट प्रारूप अपमानजनक है (जैसा कि डैनियल फिशर बताते हैं)।

आप cereal सीरियलाइजेशन लाइब्रेरी पर भी विचार करना चाहेंगे, जो बाइनरी से बेहतर है, बेहतर रखरखाव (200 9 से बाइनरी अपडेट नहीं किया गया है) और आईईईई फ्लोट प्रारूप का समर्थन built-in है।

+1

विभिन्न फ्लोट और पूर्णांक अंतहीनता के साथ बहुत कम प्लेटफार्म हैं या थे। मैं कौन भूल गया लेकिन इन जानवरों के बारे में चिंता करने के लिए बहुत दुर्लभ हैं। –

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