Каков наилучший метод для чтения двойника из двоичного файла, созданного на C?

Программа AC выплевывает последовательные удвоения в двоичный файл. Я хочу прочитать их на Python. Я попытался использовать struct.unpack('d',f.read(8))

EDIT: я использовал следующее в C, чтобы написать случайное двойное число

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

Ошибки теперь исправлены, но я не могу прочитать первое значение. для всего номера 0.000 .. он читает его как 3.90798504668055, но все остальное в порядке.

5 Solutions collect form web for “Каков наилучший метод для чтения двойника из двоичного файла, созданного на C?”

Я думаю, что вы действительно правильно читаете номер, но смущаетесь дисплеем. Когда я читаю номер из предоставленного вами файла, я получаю « 3.907985046680551e-14 » – это почти но не совсем нулевое (0.000000000000039 в расширенной форме). Я подозреваю, что ваш C-код просто печатает его с меньшей точностью, чем python.

[Edit] Я только что попробовал прочитать файл на C, и получил тот же результат (хотя немного меньше точности: 3.90799e-14) (используя printf («% g», val)), поэтому я думаю, что если это значение неверно, это произошло на стороне письма, а не на чтении.

Не могли бы вы рассказать о «не работает»? Сбой команды? Были ли данные ошибочными? Что на самом деле произошло?

Если команда разбилась:

  • Пожалуйста, поделитесь выводами ошибки команды

Если данные просто вышли неправильно:

  • Имеют ли системы, которые создают и считывают данные, одинаковые понятия? Если один из них имеет значение big-endian, а другой – little-endian, то вам нужно указать преобразование endianness в вашей строке формата.

  • Если конечность двух компьютеров одинакова, как именно данные, записанные в файл, точно ? Вы знаете? Если да, то каково было значение, записанное в файл, и какое неправильное значение вы выбрали?

Во-первых, вы пробовали рассол ? Пока еще не было кода Python … Вот какой код для чтения в двоичном формате в 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() 

Где здесь заданы одноточечные, 4-байтовые плавающие числа. Найдите любой размер данных для каждой записи и используйте это.

Для не двоичных данных вы можете сделать что-то простое:

  tmp=[] for line in open("data.dat"): tmp.append(float(line)) 
  • f.read(8) может вернуть менее 8 байт
  • Данные могут иметь различную ориентацию и / или контенту:

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

Лучший способ – использовать текстовый файл ASCII:

0.0
3,1416
+3,90798504668055

в том смысле, что он будет переносимым и будет работать с любым видом реализации с плавающей запятой.

Чтение необработанных двоичных данных из двоичного адреса памяти не является переносимым вообще и неизбежно сбой в некоторой другой реализации.

Разумеется, вы можете использовать двоичный формат для компактности, но переносная функция C, написанная в этом формате, не будет похожа на ваш фрагмент.

По крайней мере, код должен быть окружен серией ifs / ifdefs, проверяющей, что представление памяти double s, используемое текущей машиной, точно соответствует ожидаемому интерпретатором Python.

Написание такого кода было бы трудным, поэтому я предлагаю легко, чистое, портативное и удобное для пользователя решение для текста ASCII.

Это будет мое определение «лучший».

Python - лучший язык программирования в мире.