从二进制文件读取double(字节顺序?)

我有一个二进制文件,我想从中读取一个double。

在hex表示中,我在一个文件中有这8个字节(之后还有一些):

40 28 25 c8 9b 77 27 c9 40 28 98 8a 8b 80 2b d5 40 …

这应该对应于大约10的双倍值(基于该条目的含义)。

我用过

#include #include int main(int argc, char ** argv) { FILE * f = fopen(argv[1], "rb"); assert(f != NULL); double a; fread(&a, sizeof(a), 1, f); printf("value: %f\n", a); } 

但是,打印值:-261668255698743527401808385063734961309220864.000000

很明显,字节不能正确转换为double。 到底是怎么回事? 使用ftell,我可以确认正在读取8个字节。

就像整数类型一样,浮点类型受平台字节序的影响。 当我在little-endian机器上运行这个程序时:

 #include  #include  uint64_t byteswap64(uint64_t input) { uint64_t output = (uint64_t) input; output = (output & 0x00000000FFFFFFFF) << 32 | (output & 0xFFFFFFFF00000000) >> 32; output = (output & 0x0000FFFF0000FFFF) << 16 | (output & 0xFFFF0000FFFF0000) >> 16; output = (output & 0x00FF00FF00FF00FF) << 8 | (output & 0xFF00FF00FF00FF00) >> 8; return output; } int main() { uint64_t bytes = 0x402825c89b7727c9; double a = *(double*)&bytes; printf("%f\n", a); bytes = byteswap64(bytes); a = *(double*)&bytes; printf("%f\n", a); return 0; } 

然后输出是

 12.073796
 -261668255698743530000000000000000000000000000.000000

这表明您的数据以小端格式存储在文件中,但您的平台是大端。 因此,您需要在读取值后执行字节交换。 上面的代码显示了如何做到这一点。

Endianness 是惯例 。 读者和作者应该就使用什么字节顺序达成一致并坚持下去。

您应该将您的数字读作int64, 转换endianness然后转换为double。