从用 C 创建的二进制文件中读取双精度数的最佳方法是什么?
题
C 程序将连续的双精度数吐出到二进制文件中。我希望将它们读入Python。我尝试使用 struct.unpack('d',f.read(8))
编辑:我在 C 中使用以下代码编写一个随机双数
r = drand48();
fwrite((void*)&r, sizeof(double), 1, data);
错误现已修复,但我无法读取第一个值。总共 0.000..数字它读为 3.90798504668055 但其余都很好。
解决方案
我认为你实际上正在正确阅读这个数字,但却被显示屏搞糊涂了。当我从你提供的文件中读取数字时,我得到“ 3.907985046680551e-14
”。 - 这几乎不是零(扩展形式为0.000000000000039)。我怀疑你的C代码只是以比python更低的精度打印它。
[编辑]我刚尝试用C读取文件,得到相同的结果(虽然精度略低:3.90799e-14)(使用printf(“%g”,val)),所以我如果这个值不正确,就会发生在写作方面,而不是阅读。
其他提示
您能详细说明一下“不起作用”吗?命令崩溃了吗?数据出来有错吗?究竟发生了什么?
如果命令崩溃:
- 请分享命令的错误输出
如果数据只是错误:
创建和读取数据的系统是否具有相同的字节序?如果一个是大尾数,另一个是小尾数,那么您需要在格式字符串中指定尾数转换。
如果两台计算机的字节序相同,数据是如何写入文件的, 确切地?你知道吗?如果这样做,那么写入文件的值是什么以及您得到的不正确值是什么?
首先,您是否尝试过 pickle ? 还没有人展示过任何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()
其中f指定单精度,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
因为它可以移植并且在某种程度上适用于任何类型的浮点实现。
从 double
的内存地址读取原始二进制数据根本不可移植,并且在某些不同的实现中一定会失败。
当然,您可以使用二进制格式来实现紧凑性,但是以该格式编写的便携式C函数看起来根本不像您的代码段。
至少,代码应该被一系列ifs / ifdef包围,检查当前机器使用的 double
的内存表示与Python解释器预期的内存表示完全匹配。
编写这样的代码会很困难,这就是为什么我建议使用简单,干净,可移植和人类可读的ASCII文本解决方案。
这将是我的定义为“best”。