Quelle est la meilleure méthode pour lire un double à partir d'un fichier binaire créé en C?

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

  •  08-07-2019
  •  | 
  •  

Question

Un programme C crée des doubles consécutifs dans un fichier binaire. Je souhaite les lire en Python. J'ai essayé d'utiliser struct.unpack ('d', f.read (8))

EDIT: J'ai utilisé ce qui suit en C pour écrire un nombre double aléatoire

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

Les erreurs sont maintenant corrigées mais je ne peux pas lire la première valeur. pour un tout 0,000 .. nombre il le lit comme 3.90798504668055 mais le reste va bien.

Était-ce utile?

La solution

Je pense que vous lisez le numéro correctement, mais que l’écran vous laisse confus. Lorsque je lis le numéro du fichier fourni, le message " 3.907985046680551e-14 " - c'est presque mais pas tout à fait zéro (0.000000000000039 sous forme développée). Je soupçonne que votre code C l’imprime avec moins de précision que python.

[Éditer] Je viens d'essayer de lire le fichier en C et j'obtiens le même résultat (avec un peu moins de précision: 3.90799e-14) (en utilisant printf ("% g", val)), alors je pense que si cette valeur est incorrecte, il s’agit du côté écriture, plutôt que de la lecture.

Autres conseils

Pourriez-vous s'il-vous-plaît préciser "n'a pas fonctionné"? La commande est-elle tombée en panne? Les données sont-elles erronées? Qu'est-ce qui s'est réellement passé?

Si la commande a échoué:

  • Veuillez partager le résultat d'erreur de la commande

Si les données sont simplement erronées:

  • Les systèmes qui créent et lisent les données ont-ils la même finalité? Si l’un est big-endian et l’autre little-endian, vous devez spécifier une conversion d’endianisme dans votre chaîne de format.

  • Si la finalité des deux ordinateurs est la même, comment les données ont-elles été écrites dans le fichier, exactement ? Savez-vous? Si vous le faites, quelle est la valeur écrite dans le fichier et quelle est la valeur incorrecte que vous avez obtenue?

D'abord, avez-vous essayé pickle ? Personne n'a encore montré de code Python ... Voici du code pour lire en binaire en python:

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

Où le f spécifié ici, nombres flottants à 4 octets à simple précision. Trouvez la taille de vos données par entrée et utilisez-la.

Pour les données non binaires, vous pouvez faire quelque chose de simple comme ceci:

   tmp=[]
   for line in open("data.dat"):
                tmp.append(float(line))
  • f.read (8) peut renvoyer moins de 8 octets
  • Les données peuvent avoir un alignement et / ou une finalité différents:

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

La meilleure méthode consisterait à utiliser un fichier texte ASCII:

  

0.0
  3.1416
  3.90798504668055

en ce sens qu'il serait portable et fonctionnerait avec n'importe quel type d'implémentation en virgule flottante dans une certaine mesure.

La lecture de données binaires brutes à partir de l'adresse mémoire d'un double n'est pas du tout portable et doit échouer dans une implémentation différente.

Vous pouvez bien sûr utiliser un format binaire pour plus de compacité, mais une fonction C portable écrivant dans ce format ne ressemblerait pas du tout à votre extrait.

À tout le moins, le code devrait être entouré d'une série de ifs / ifdefs vérifiant que la représentation en mémoire de double utilisée par la machine actuelle correspond exactement à celle attendue par l'interpréteur Python.

L'écriture d'un tel code serait difficile, c'est pourquoi je suggère la solution simple, propre, portable et lisible par l'homme du texte ASCII.

Ce serait ma définition de "meilleur".

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top