Thus, if you have a minute, try "%.20f" instead of %f.
:)
Or, how about this:
#include <stdio.h>
int main(void)
{
for (int prec = 0; prec < 25; prec++)
{
printf("%.*f\n", prec, 57.0 / 100.0 * 100.0);
}
return 0;
}
Output:
57
57.0
57.00
57.000
57.0000
57.00000
57.000000
57.0000000
57.00000000
57.000000000
57.0000000000
57.00000000000
57.000000000000
57.0000000000000
56.99999999999999
56.999999999999993
56.9999999999999929
56.99999999999999289
56.999999999999992895
56.9999999999999928946
56.99999999999999289457
56.999999999999992894573
56.9999999999999928945726
56.99999999999999289457264
56.999999999999992894572642
The 64 bit double will store 15 decimal digits reliably. That is to say, if you have a decimal figure with 15 significant digits, which is in range of the type (and not mapping to a denormal value close to zero and whatnot), all 15 digits are representable and can be recovered.
In the reverse direction, you need about 17 decimal digits in order to capture an 64 bit double as decimal text such that the exact value can be recovered from the decimal text.
Thus in the above loop's output, once we are past 17 digits (including the 56 before the decimal point), we are no longer seeing any new data, just a continuation of the fraction.
And, notice how the last value that is still 57.000.... is exactly 15 digits wide. The next row is 16 digits, and that's where we now have 56.9999.... but 16 digits isn't quite enough to capture the value. I believe the next row gets us that: the ...99929. If we use that as a constant, any digits after that make no difference.
Programming languages which, by default, print floating-point values to 15 digits will show the nice result .1 + .2 = .3.
This is what I did in TXR Lisp.
1> *print-flo-precision*
15
2> (+ .1 .2)
0.3
3> (set *print-flo-precision* 16)
16
4> (+ .1 .2)
0.3
5> (set *print-flo-precision* 17)
17
6> (+ .1 .2)
0.30000000000000004
We can see there is no value difference in digits beyond 17:
7> (eq 0.30000000000000004 0.300000000000000049)
t
8> (eq 0.30000000000000004 0.300000000000000040)
t
To get different value (different floating-point bit pattern), we need a difference in the 17th digit. And not just a single increment:
9> (eq 0.30000000000000004 0.30000000000000003)
t
10> (eq 0.30000000000000004 0.30000000000000002)
t
The last digit being 3 and 2 is still mapping to the same value. When we make it 1, we start getting a different float:
11> (eq 0.30000000000000004 0.30000000000000001)
nil