Reputation: 1469
I have a piece of code that writes some floats to a binary file, and later reads them back. The read data is different from the written data.
Why does this happen? Can it be fixed? Here is my code:
#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;
}
And this is the output:
write: 0.3721548 0.3721548 0.3475495
read: 0.3721550 0.3721550 0.3475490
Upvotes: 0
Views: 1545
Reputation: 35164
Though opening your files in binary mode, when using >>
- and <<
-operators, you actually "serialize" your data into a textual representation. When using <<
on data type float
, the value it by default rounded to a precision of 6. So you "loose" precision/information while writing, which cannot be reproduced when reading in the textual float representation later. So the difference in your output is due to the fact that you write to files values rounded to 6 digits, while you printf
the values with a precision of 7.
To demonstrate that this is actually the case, test to set the <<
-precision to 7 (right before actually writing the values):
file << std::setprecision(7);
But actually you should write your data in binary format:
file.write((const char*)a, sizeof(a));
...
file2.read((char*)b,sizeof(b));
Upvotes: 1
Reputation: 206747
Using the flag std::ios::binary
changes how newline characters are written to and read from a file. See http://en.cppreference.com/w/cpp/io/c#Binary_and_text_modes for more details.
It does not change how formatted input and output are written/read.
If you want to retain the accuracy of the numbers, use ostream::write
and istream::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]);
Upvotes: 0