【问题标题】:Different values when writing and reading floats to binary file将浮点数写入和读取二进制文件时的不同值
【发布时间】:2017-06-09 21:09:22
【问题描述】:

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

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

#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 %.7f\n", 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 %.7f\n", b[0], b[1], b[2]);
    file2.close();
    return 0;
}

这是输出:

write:  0.3721548 0.3721548 0.3475495
read:   0.3721550 0.3721550 0.3475490

【问题讨论】:

  • 在您喜欢的文本编辑器中检查文件的内容。您正在编写数字的十进制表示,精度为 6 位。
  • 你的“二进制”在这里没有任何区别。您正在使用格式化的输出函数(运算符&lt;&lt;)编写数据,这意味着您正在将其编写为文本。稍后您将其阅读为 text。如果您想将数据写入/读取为二进制数据,请使用二进制输入/输出函数。
  • 当您写出数据时,您可能希望在数字之间添加空格以将它们分开。
  • @IgorTandetnik 是的,我知道,如果我只打印 6 位数字,它们看起来是一样的。但不同之处不仅在于打印。如果我尝试平等检查,我仍然会得到 false
  • 您正在以 6 位精度将数字写入文件。你在那个时候四舍五入,失去了额外的精度。当然,当您从文件中读取这些四舍五入的数字时,它们与原始数字不匹配。

标签: c++ io


【解决方案1】:

虽然以二进制模式打开文件,但在使用 &gt;&gt;- 和 &lt;&lt;- 运算符时,您实际上将数据“序列化”为文本表示形式。在数据类型&lt;&lt; 上使用float 时,默认情况下它的值四舍五入到精度为6。因此,您在写入时“松散”了精度/信息,稍后在文本浮点表示中读取时无法重现。因此,输出的差异是由于您写入文件的值四舍五入为 6 位,而您 printf 的值的精度为 7。

为了证明确实如此,测试将&lt;&lt;-precision 设置为7(在实际写入值之前):

file << std::setprecision(7);

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

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

【讨论】:

  • 嗯,好的。我不知道序列化。现在说得通了。
【解决方案2】:

使用标志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 %.7f\n", 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 %.7f\n", b[0], b[1], b[2]);

【讨论】:

    猜你喜欢
    • 2016-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    • 2015-06-16
    相关资源
    最近更新 更多