Write a float with full precision in C++
In C++, can I write and read back a float (or double) in text format without losing precision?
Consider the following:
float f = ...;
{
std::ofstream fout("file.txt");
// Set some flags on fout
fout << f;
}
float f_read;
{
std::ifstream fin("file.txt");
fin >> f;
}
if (f != f_read) {
std::cout << "precision lost" << std::endl;
}
I understand why precision is lost sometimes. However, if I print the value with enough digits, I should be able to read back the exact 开发者_如何学Csame value.
Is there a given set of flags that is guaranteed to never lose precision? Would this behaviour be portable across platforms?
If you don't need to support platforms that lack C99 support (MSVC), your best bet is actually to use the %a
format-specifier with printf
, which always generates an exact (hexadecimal) representation of the number while using a bounded number of digits. If you use this method, then no rounding occurs during the conversion to a string or back, so the rounding mode has no effect on the result.
Have a look at this article: How to Print Floating-Point Numbers Accurately and also at that one: Printing Floating-Point Numbers Quickly and Accurately.
It is also mentioned on stackoverflow here, and there is some pointer to an implementation here.
if I print the value with enough digits, I should be able to read back the exact same value
Not if you write it in decimal - there's not an integer relationship between the number of binary digits and the number of decimal digits required to represent a number. If you print your number out in binary or hexadecimal, you'll be able to read it back without losing any precision.
In general, floating point numbers are not portable between platforms in the first place, so your text representation is not going to be able to bridge that gap. In practice, most machines use IEEE 754 floating point numbers, so it'll probably work reasonably well.
You can't necessarily print the exact value of a "power of two" float in decimal.
Think of using base three to store 1/3, now try and print 1/3 in decimal perfectly.
For solutions see: How do you print the EXACT value of a floating point number?
精彩评论