2009-03-10 24 views
5

ए सी प्रोग्राम एक द्विआधारी फ़ाइल में लगातार युगल को थूकता है। मैं उन्हें पायथन में पढ़ना चाहता हूं। मैं struct.unpack('d',f.read(8))सी में बनाई गई बाइनरी फ़ाइल से डबल पढ़ने का सबसे अच्छा तरीका क्या है?

संपादित उपयोग करने की कोशिश: मैं एक यादृच्छिक डबल संख्या

r = drand48(); 
fwrite((void*)&r, sizeof(double), 1, data); 

त्रुटियाँ अब ठीक लिखने के लिए सी में निम्नलिखित का इस्तेमाल किया है, लेकिन मैं पहले मूल्य नहीं पढ़ सकता। सभी 0.000 के लिए .. संख्या यह इसे 3.90798504668055 के रूप में पढ़ती है लेकिन शेष ठीक हैं।

+0

यह गलत अंतहीनता से जुड़ा हो सकता है (सबसे पहले कम से कम महत्वपूर्ण बाइट या नहीं)। दिखाएं कि आप कौन से बाइट्स को पढ़ने की कोशिश कर रहे हैं। – jfs

+0

मुझे खेद है। मैंने लगभग समस्या को ठीक किया है इसलिए मैंने इसका उत्तर दिया। मैं पहले नंबर को ठीक से पढ़ना चाहता हूं। – gnosio

+0

क्या आप उस फ़ाइल के पहले 40 बाइट्स का डंप प्रदान कर सकते हैं जिसके साथ आप वर्तमान में इसे पढ़ने के लिए उपयोग कर रहे हैं? –

उत्तर

3

:

गैर बाइनरी डेटा के लिए आप कुछ इस तरह सरल कर सकता है। जब मैं आपकी प्रदत्त फ़ाइल से नंबर पढ़ता हूं, तो मुझे "3.907985046680551e-14" मिलता है - यह लगभग शून्य नहीं है (विस्तारित रूप में 0.000000000000039)। मुझे संदेह है कि आपका सी कोड सिर्फ इसे पाइथन की तुलना में कम परिशुद्धता के साथ प्रिंट कर रहा है।

[संपादित करें] मैंने सी में फ़ाइल पढ़ने की कोशिश की है, और मुझे एक ही परिणाम मिलता है (हालांकि थोड़ा कम परिशुद्धता: 3.9079 9ई -14) (printf ("% g", val) का उपयोग करके, इसलिए मैं सोचें कि क्या यह मान गलत है, यह पढ़ने के बजाए लेखन पक्ष पर हुआ है।

+0

हे ब्रायन, आपने इसे खींचा। मैं इसे विस्तारित करने के लिए आलसी था :(सटीकता 2 अलग-अलग मूल्यों का कारण है। सहायता के लिए धन्यवाद। – gnosio

1

क्या आप कृपया "काम नहीं किया" पर विस्तृत जानकारी दे सकते हैं? क्या आदेश दुर्घटनाग्रस्त हो गया? क्या डेटा गलत हो गया? वास्तव में क्या हुआ था?

तो आदेश दुर्घटनाग्रस्त:

  • आदेश

की त्रुटि उत्पादन साझा करें डेटा बस गलत बाहर आया, तो:

  • प्रणाली है कि बनाने करो और डेटा को एक ही अंतहीनता पढ़ें? यदि कोई बड़ा एंडियन है, और दूसरा छोटा-अंत है, तो आपको अपनी प्रारूप स्ट्रिंग में एंडियनियंस रूपांतरण निर्दिष्ट करना होगा।

  • यदि दो कंप्यूटरों की अंतहीनता समान है, तो फ़ाइल को लिखा गया डेटा, बिल्कुल? क्या आप जानते है? यदि आप करते हैं, तो फ़ाइल में लिखा गया मूल्य क्या था और आपके द्वारा गलत मूल्य क्या था?

0
  • f.read(8) कम से कम 8 वापस कर सकती है बाइट्स
  • डाटा अलग संरेखण और/या endianness हो सकता है:

    >>> for c in '@=<>': 
    ...  print repr(struct.pack(c+'d', -1.05)) 
    ... 
    '\xcd\xcc\xcc\xcc\xcc\xcc\xf0\xbf' 
    '\xcd\xcc\xcc\xcc\xcc\xcc\xf0\xbf' 
    '\xcd\xcc\xcc\xcc\xcc\xcc\xf0\xbf' 
    '\xbf\xf0\xcc\xcc\xcc\xcc\xcc\xcd' 
    >>> struct.unpack('<d', '\xbf\xf0\xcc\xcc\xcc\xcc\xcc\xcd') 
    (-6.0659880001157799e+066,) 
    >>> struct.unpack('>d', '\xbf\xf0\xcc\xcc\xcc\xcc\xcc\xcd') 
    (-1.05,) 
    
0

सबसे अच्छा विधि एक का उपयोग किया जाएगा ASCII पाठ फ़ाइल:

0,0
3,1416
3,90798504668055

में है कि यह पोर्टेबल हो सकता है और एक हद तक बिंदु कार्यान्वयन चल के किसी भी प्रकार के साथ काम करेगा।

double के स्मृति पते से कच्चे बाइनरी डेटा को पढ़ना बिल्कुल पोर्टेबल नहीं है, और कुछ अलग कार्यान्वयन में विफल होने के लिए बाध्य है।

आप निश्चित रूप से कॉम्पैक्टनेस के लिए एक बाइनरी प्रारूप का उपयोग कर सकते हैं, लेकिन उस प्रारूप में एक पोर्टेबल सी फ़ंक्शन लेखन आपके स्निपेट की तरह नहीं दिखता है।

कम से कम, कोड को ifs/ifdefs की एक श्रृंखला से घिरा होना चाहिए कि वर्तमान मशीन द्वारा उपयोग किए गए double एस की स्मृति प्रस्तुति पाइथन दुभाषिया द्वारा अपेक्षित एक से मेल खाती है।

ऐसे कोड लिखना मुश्किल होगा, यही कारण है कि मैं एएससीआईआईआई पाठ के आसान, स्वच्छ, पोर्टेबल और मानव-पठनीय समाधान का सुझाव दे रहा हूं।

यह मेरी "सर्वश्रेष्ठ" की परिभाषा होगी।

+0

के बीच डबल्स हैं हाय ऐब, मेरी इच्छा है कि मैं ऐसा कर सकता हूं लेकिन यह एक मेमोरी डंप है और मेरे पास नहीं है इसका निर्यात कैसे किया जाता है पर नियंत्रण। मुझे अनपैक के साथ अच्छी सफलता मिल रही है लेकिन किसी कारण से पहले डबल को सही ढंग से नहीं पढ़ा जाता है। – gnosio

+0

मैंने अनुमान लगाया था, लेकिन अभी भी भविष्य के पाठकों के लिए अपना मुद्दा बनाना चाहता था। मुझे खुशी है कि आपने अपनी समस्या हल की है। – aib

1

सबसे पहले, आपने pickle को आजमाया है? अभी तक कोई भी किसी भी अजगर कोड से पता चला है ... यहाँ अजगर में बाइनरी में पढ़ने के लिए कुछ कोड है:

import Numeric as N 
import array 
filename = "tmp.bin" 
file = open(filename, mode='rb') 
binvalues = array.array('f') 
binvalues.read(file, num_lon * num_lat) 
data = N.array(binvalues, typecode=N.Float) 

file.close() 

कहाँ च यहाँ निर्दिष्ट केवल एक परिशुद्धता, 4 बाइट चल, संख्या। प्रति प्रविष्टि आपका डेटा जो भी आकार है उसे ढूंढें और इसका उपयोग करें। मुझे लगता है कि आप वास्तव में सही ढंग से नंबर पढ़ रहे हैं, लेकिन प्रदर्शन से उलझन में हो रहे

tmp=[] 
    for line in open("data.dat"): 
       tmp.append(float(line)) 
+0

अरे एलेक्स, मैंने अचार की कोशिश की लेकिन मेरी समस्या के लिए मुझे सभी मूल्यों की गारंटी नहीं है। वे इंट्स, फ्लोट्स या डबल्स हो सकते हैं। मुझे पता है कि पढ़ने के लिए मूल्य और मूल्य का प्रकार है। हालांकि मदद के लिए धन्यवाद :) – gnosio

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