簡體   English   中英

從二進制文件讀取並轉換為兩倍?

[英]Reading from binary file and converting to double?

我試圖編寫一個讀取二進制文件並將其轉換為數據類型的C程序。 我正在使用頭命令head -c 40000 /dev/urandom > data40.bin生成一個二進制文件。 該程序適用於int和char數據類型,但不能執行double。 這是程序的代碼。

void double_funct(int readFrom, int writeTo){
    double buffer[150];
    int a = read(readFrom,buffer,sizeof(double));
    while(a!=0){
        int size = 1;
        int c=0;

         for(c=0;c<size;c++){
            char temp[100];
            int x = snprintf(temp,100,"%f ", buffer[c]);
            write(writeTo, temp, x);
        }
        a = read(readFrom,buffer,sizeof(double));
    }
}

這是有效的char函數

void char_funct(int readFrom, int writeTo){
    char buffer[150];
    int a = read(readFrom,buffer,sizeof(char));
    while(a!=0){
        int size = 1;
        int c=0;

        for(c=0;c<size;c++){
            char temp[100]=" ";
            snprintf(temp,100,"%d ", buffer[c]);
            write(writeTo, temp, strlen(temp));
        }
        a = read(readFrom,buffer,sizeof(char));
    }
}

問題是使用char我需要用wc -w file獲取40000個單詞,然后我將它們獲取。 現在有了double我得到了隨機的單詞數量,但是理論上我應該從40000字節的數據中得到5000,但是我得到4000到15000之間的隨機數,對於char我得到40000,就像它應該為一個字符提供1個字節。

我不知道這是什么錯誤,相同的代碼適用於int ,我從40000字節的數據中獲得10000個單詞。

主要問題似乎是您的temp數組不足以容納您的printf格式和數據。 IEEE-754 double的十進制指數范圍為-308至+308。 您正在以"%f"格式打印雙打,這將產生純十進制表示形式。 由於未指定精度,因此默認精度為6。 這可能需要多達1(符號)+ 309(數字)+1(小數點)+6(尾隨小數位)+1(終止符)字符(共318個),但是您只能容納100個空間。

您使用snprintf()打印到緩沖區,因此不會超出那里的數組范圍,但是snprintf()返回的是所需的字節數,減去終止符所需的字節數。 那是您write()的字節數,並且在許多情況下確實會超出緩沖區。 您會在輸出中看到結果。

其次,您還會在輸出中看到大量的0.00000 ,這是因為將小數舍入到6進制的精度。

如果更改打印數字的格式,可能會獲得更好的成功。 例如, "%.16e "將為您提供指數格式的輸出,總共有17個有效數字(小數點前一位)。 這將不需要在內存或磁盤上占用過多的空間,並且它將准確地傳遞所有數字,而不管其規模如何,再次假設您的double是按照IEEE 754表示的。如果您願意,還可以消除(非常安全的)假設通過使用@chux在注釋中建議的變體來更改IEEE 754格式。 那將是最安全的方法。

還有一件事:IEEE浮點支持無限性和多個非數字值。 與普通FP編號相比,這些編號的數量很少,但是您偶爾還是會碰到其中之一。 它們可能會被轉換為輸出,但是您可能要考慮是否需要專門處理它們。

暫無
暫無

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

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