简体   繁体   English

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

[英]Reading double from binary file (byte order?)

I have a binary file, and I want to read a double from it.我有一个二进制文件,我想从中读取一个double。

In hex representation, I have these 8 bytes in a file (and then some more after that):在十六进制表示中,我在一个文件中有这 8 个字节(然后还有更多):

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

This should correspond to a double value of around 10 (based on what that entry means).这应该对应于大约 10 的双精度值(基于该条目的含义)。

I have used我用过了

#include<stdio.h>
#include<assert.h>

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);
}

However, that prints value: -261668255698743527401808385063734961309220864.000000但是,打印值:-261668255698743527401808385063734961309220864.000000

So clearly, the bytes are not converted into a double correctly.很明显,字节没有正确转换为双精度。 What is going on?到底是怎么回事? Using ftell, I could confirm that 8 bytes are being read.使用 ftell,我可以确认正在读取 8 个字节。

Just like integer types, floating point types are subject to platform endianness.就像整数类型一样,浮点类型也受平台字节序的影响。 When I run this program on a little-endian machine:当我在小端机器上运行这个程序时:

#include <stdio.h>
#include <stdint.h>

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;
}

Then the output is然后输出是

12.073796
-261668255698743530000000000000000000000000000.000000

This shows that your data is stored in the file in little endian format, but your platform is big endian.这表明您的数据以小端格式存储在文件中,但您的平台是大端格式。 So, you need to perform a byte swap after reading the value.因此,您需要在读取值后执行字节交换。 The code above shows how to do that.上面的代码展示了如何做到这一点。

Endianness is convention .字节序是约定俗成的 Reader and writer should agree on what endianness to use and stick to it.读者和作者应该就使用什么字节序达成一致并坚持下去。

You should read your number as int64, convert endianness and then cast to double.您应该将您的数字读为 int64, 转换字节序,然后转换为双精度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM