簡體   English   中英

從二進制文件中讀取 double(字節順序?)

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

我有一個二進制文件,我想從中讀取一個double。

在十六進制表示中,我在一個文件中有這 8 個字節(然后還有更多):

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

這應該對應於大約 10 的雙精度值(基於該條目的含義)。

我用過了

#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

很明顯,字節沒有正確轉換為雙精度。 到底是怎么回事? 使用 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

這表明您的數據以小端格式存儲在文件中,但您的平台是大端格式。 因此,您需要在讀取值后執行字節交換。 上面的代碼展示了如何做到這一點。

字節序是約定俗成的 讀者和作者應該就使用什么字節序達成一致並堅持下去。

您應該將您的數字讀為 int64, 轉換字節序,然后轉換為雙精度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM