浮点长度在32到40位之间变化

Yel*_*low 26 c c++ visual-studio-2010

float值导出到文件时遇到了一个奇怪的问题.我希望每个浮点数具有相同的长度(显然),但我的程序有时会将其输出为32位数,有时输出为40位数.仍然显示此行为的程序的最小工作示例是:

#include <stdio.h>

const char* fileName = "C:/Users/Path/To/TestFile.txt";
float array [5];

int main(int argc, char* argv [])
{
    float temp1 = 1.63006e-33f;
    float temp2 = 1.55949e-32f;

    array[0] = temp1;
    array[1] = temp2;
    array[2] = temp1;
    array[3] = temp2;
    array[4] = temp2;

    FILE* outputFile;
    if (!fopen_s(&outputFile, fileName, "w")) 
    {
        fwrite(array, 5 * sizeof(float), 1, outputFile);
        fclose(outputFile);
    }

     return true;
}
Run Code Online (Sandbox Code Playgroud)

我希望输出文件包含正好20(5×4)个字节,每个字节代表一个浮点数.但是,我明白了:

 8b 6b 07 09      // this is indeed 1.63006e-33f 
 5b f2 a1 0d 0a   // I don't know what this is but it's a byte too long
 8b 6b 07 09      
 5b f2 a1 0d 0a   
 5b f2 a1 0d 0a 
Run Code Online (Sandbox Code Playgroud)

因此浮点数temp2需要5个字节而不是4个字节,并且文件的总长度为23.这怎么可能?!这个数字不是很小,以至于它们是次正规数,我想不出为什么会有大小差异的任何其他原因.

我在64位Windows 7系统上使用MSVC 2010编译器.

注意: 我已经在这里问了一个非常相似的问题,但是当我意识到这个问题比较笼统时,我决定以更简洁的方式重新发布它. QDataStream有时使用32位浮点数,有时使用40位浮点数

Rei*_*ica 41

问题是在Windows上,您必须区分文本和二进制文件.您将文件作为文本打开,这意味着0d在每次0a(换行)写入之前插入(回车).像这样打开文件:

if (!fopen_s(&outputFile, fileName, "wb"))
Run Code Online (Sandbox Code Playgroud)

和以前一样,它应该工作.

  • 此外,如果您正在编写二进制文件,您可能不应该给它一个".txt"扩展名.这只会让每个人感到困惑. (3认同)

aut*_*tic 12

你不是在写文字; 你正在编写二进制数据......但是,你的文件是开放的,用于编写text("w")而不是编写binary("wb").因此,fwrite()正在转化'\n'"\r\n".

改变这个:

if (!fopen_s(&outputFile, fileName, "w")) 
Run Code Online (Sandbox Code Playgroud)

对此:

if (!fopen_s(&outputFile, fileName, "wb")) 
Run Code Online (Sandbox Code Playgroud)

"wb",b代表二进制模式.