Was ist die beste Methode, ein Doppel aus einer Binärdatei in C erstellt zu lesen?

StackOverflow https://stackoverflow.com/questions/631607

  •  08-07-2019
  •  | 
  •  

Frage

Ein C-Programm spuckt in Folge verdoppelt in eine Binärdatei aus. Ich wünsche sie in Python zu lesen. Ich habe versucht, mit struct.unpack('d',f.read(8))

EDIT: Früher habe ich die folgenden in C eine zufällige doppelte Anzahl schreiben

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

Die Fehler werden behoben, aber ich kann den ersten Wert nicht lesen. für ein all 0.000 .. Zahl liest es als 3,90798504668055 aber der Rest ist in Ordnung.

War es hilfreich?

Lösung

Ich glaube, Sie sind die Nummer richtig tatsächlich zu lesen, aber sind immer durch die Anzeige verwirrt. Wenn ich die Nummer von Ihnen zur Verfügung gestellten Datei zu lesen, ich „3.907985046680551e-14“ bekommen - das ist fast, aber nicht ganz Null (,000000000000039 in erweiterter Form). Ich vermute, dass Ihr C-Code druckt es nur mit weniger Präzision als Python ist.

[Bearbeiten] Ich habe gerade versucht, die Datei in C zu lesen, und ich bekomme das gleiche Ergebnis (wenn auch etwas weniger Präzision: 3.90799e-14) (unter Verwendung von printf ( "% g", val)), so dass ich denke, wenn dieser Wert nicht korrekt ist, ist es auf der Schreibseite passiert ist, anstatt die Lesung.

Andere Tipps

Könnten Sie bitte sorgfältig ausarbeiten, „hat nicht funktioniert“? Hat der Befehl zum Absturz? Kommen die Daten falsch aus? Was ist eigentlich passiert?

Wenn der Befehl abgestürzt:

  • Bitte teilen Sie die Fehlerausgabe des Befehls

Wenn die Daten einfach herauskommen falsch:

  • Die Systeme, die die Daten die gleiche endianness erstellen und lesen? Wenn ein Big-Endian ist, und das andere ist Little-Endian, dann müssen Sie eine Endian-Umsetzung in Ihrem Format-String angeben.

  • Wenn die endianness der beiden Rechner die gleichen sind, wie wurden die Daten in die Datei geschrieben, genau ? Wissen Sie? Wenn Sie das tun, was war dann der Wert in die Datei geschrieben und was war der falsche Wert, den Sie stieg aus?

Als erstes haben Sie versucht, Gurke ? Niemand hat einen Python-Code noch gezeigt ... Hier einige Code sind binär in Python zum Lesen:

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()

Wenn die f hier mit einfacher Genauigkeit angegeben, 4-Byte-Fließ, Zahlen. Finden Sie, was Größe Ihrer Daten pro Eintrag und verwendet diesen.

Für nicht Binärdaten Sie etwas Einfaches wie dies tun könnte:

   tmp=[]
   for line in open("data.dat"):
                tmp.append(float(line))
  • f.read(8) könnte zurückkehren weniger als 8 Bytes
  • Die Daten könnten unterschiedliche Ausrichtung haben und / oder Endian:

    >>> 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,)
    

Die am besten Methode wäre, eine ASCII-Textdatei zu verwenden:

  

0,0
  3,1416
  3,90798504668055

, dass es tragbar sein würde, und arbeitet mit jeder Art von Punkt Implementierung zu einem gewissen Grad schweben.

Lesen unformatierte binäre Daten aus einer Speicheradresse des double ist überhaupt nicht tragbar, und ist verpflichtet, in einigen anderen Implementierung zum Scheitern verurteilt.

Sie natürlich ein binäres Format für Kompaktheit, sondern ein portable C-Funktion Schreiben in diesem Format aussehen würde nicht wie Ihr Snippet verwenden.

Am allerwenigsten, sollte der Code durch eine Reihe von ifs / ifdefs umgeben sein, dass der Speicher Darstellung doubles von der aktuellen Maschine genau das auch vom Interpreter Python erwartet.

so das Schreiben von Code wäre schwierig, weshalb ich vorschlage, die einfache, saubere, tragbare und menschenlesbare Lösung von ASCII-Text.

Dies wäre mein Definition von "best".

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top