从用 C 创建的二进制文件中读取双精度数的最佳方法是什么?

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

  •  08-07-2019
  •  | 
  •  

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”。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top