Why the printf below prints 123456.984 instead of 123456.988?
#include <stdio.h>
int main()
{
printf("%.3f\n", 123456.987654);
return 0;
}
Edit: i did a mistake, the right printf is:
printf("%.3f\n", 123456.987654f);
Why the printf below prints 123456.984 instead of 123456.988?
#include <stdio.h>
int main()
{
printf("%.3f\n", 123456.987654);
return 0;
}
Edit: i did a mistake, the right printf is:
printf("%.3f\n", 123456.987654f);
The error is definitively related to floating point precision. It could be reproduced with float
constants.
Executing this printf()
with a float constant shows the behavior that you describe. If you pass a double constant, however, the result is as expected:
#include <stdio.h>
int main()
{
printf("%.3f\n", 123456.987654f); // float: insufficient precision .984
printf("%.3f\n", 123456.987654); // double: better precision .988
// unsuffixed floating point constants are double
return 0;
}
This is due to approximation in the internal representation of the floating point numbers, that use power of two and fractions of power of twos to represent the numbers. The closest representation corresponding to a number might not be close enough when converting back to decimal.
This strange rounding behavior is implementation dependent: The C standard does not specify which floating point representation has to be used.
Your compiler you use is certainly based on IEEE 754 standard. On this great web page, you can verify how a chosen floating point number is encoded using IEEE in single precision: for 123456.987654, almost the full range of bits is used and the closest number that can be represented in single precision is 123456.984375.
On my computer the programme below (compiled with gcc) prints out
123456.988
123456.988
123456.984
Was the code in your question actually what was showing the problem, or was there a float involved? If there was a float then the problem is that a float only has enough precision for about 7 figures. The closest float to your number, when printed to 3 decimal places is around 123456.984
#include <stdio.h>
#include <stdlib.h>
int main( void)
{
printf("%.3f\n", 123456.987654);
double d = 123456.987654;
printf("%.3f\n", d);
float f = 123456.987654;
printf("%.3f\n", f);
return EXIT_SUCCESS;
}
The issue you have seems to be implementation/compiler-specific (maybe even compilation- or execution-dependent). It is not reproducible for me.
With gcc, version 9.1 and clang, version 9.0 on Online Godbolt compiler and executor the output is 123456.988
for both.
Here is the Link.