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

标签 c io double

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

在十六进制表示中,我在一个文件中有这 8 个字节(然后还有更多):

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

这应该对应于 10 左右的 double 值(基于该条目的含义)。

我用过

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

但是,打印 值:-261668255698743527401808385063734961309220864.000000

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

最佳答案

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

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

那么输出是

12.073796
-261668255698743530000000000000000000000000000.000000

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

关于c - 从二进制文件中读取 double (字节顺序?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25929013/

相关文章:

c++ - 哪些平台有 8 位字符以外的内容?

c - 如果我已经有权访问系统,那么 system() 函数的用途是什么?

java - FileReader 读取文本文件时出错

java - 将 Double 数组转换为 BigDecimals 数组

c# - 如何将字符串列表转换为 double ?

C编程段错误

C:为什么从命令行获取字符串比在程序中设置字符串更容易被识别?

c - 终端不允许我打印指向末尾没有换行符的字符串的指针 - C

c - 从C中的文件中逐行读取

c# - 在 C# 中使用数组和指针与 C DLL