写入和读取时的不同值浮点到二进制文件

Different values when writing and reading floats to binary file

本文关键字:二进制文件 读取      更新时间:2023-10-16

我有一段代码将一些浮点数写入二进制文件,然后读回它们。读取的数据与写入的数据不同。

为什么会这样?可以修复吗?这是我的代码:

#include <fstream>
using namespace std;
int main ( int argc, char *argv[] )
{
    float a[3];
    float b[3];
    a[0] = 0.3721548;
    a[1] = 0.3721548;
    a[2] = 0.3475495;
    ofstream file("mlt_data", std::ios::binary);
    file << a[0];
    file << a[1];
    file << a[2];
    printf("write: t%.7f %.7f %.7fn", a[0], a[1], a[2]);
    file.close();
    ifstream file2("mlt_data", std::ios::binary);
    file2 >> b[0];
    file2 >> b[1];
    file2 >> b[2];
    printf("read: t%.7f %.7f %.7fn", b[0], b[1], b[2]);
    file2.close();
    return 0;
}

这是输出:

write:  0.3721548 0.3721548 0.3475495
read:   0.3721550 0.3721550 0.3475490

虽然以二进制模式打开文件,但在使用 >><< 运算符时,您实际上是将数据"序列化"为文本表示形式。当对数据类型 float 使用 << 时,默认情况下该值四舍五入为精度 6。因此,您在写作时"松散"了精度/信息,这在以后阅读文本浮动表示时无法重现。因此,输出的差异是由于您写入文件的值四舍五入为 6 位,而您以 7 的精度printf值。

为了证明实际情况确实如此,请进行测试以将<<精度设置为 7(就在实际写入值之前(:

file << std::setprecision(7);

但实际上你应该以二进制格式写入数据:

file.write((const char*)a, sizeof(a));
...
file2.read((char*)b,sizeof(b));

使用标志std::ios::binary更改对文件的写入和读取换行符的方式。有关更多详细信息,请参阅 http://en.cppreference.com/w/cpp/io/c#Binary_and_text_modes。

它不会更改格式化输入和输出的写入/读取方式。

如果要保留数字的准确性,请使用 ostream::writeistream::read

ofstream file("mlt_data", std::ios::binary);
fire.write(reinterpret_cast<char const*>(a), sizeof(a));
printf("write: t%.7f %.7f %.7fn", a[0], a[1], a[2]);
file.close();
ifstream file2("mlt_data", std::ios::binary);
file2.read(reinterpret_cast<char*>(b), sizeof(b));
printf("read: t%.7f %.7f %.7fn", b[0], b[1], b[2]);