I have this code in C where I\'ve declared 0.1 as double.
#include
int main() {
double a = 0.1;
printf(\"a is %0.56f\\n\", a);
retu
With MinGW g++ (and gcc) 7.3.0 your results are reproduced exactly.
This is a pretty weird case of Undefined Behavior.
The Undefined Behavior is due to using printf
without including an appropriate header, ¹violating the “shall” in
” A translation unit shall include a header only outside of any declaration or definition, and shall include the header lexically before the first reference in that translation unit to any of the entities declared in that header. No diagnostic is required.
In the C++ code change
to
, to get valid C++ code, and you get the same result as with the C program.
Why does the C++ code even compile?
Well, unlike C, in C++ a standard library header is allowed to drag in any other header. And evidently with g++ the
header drags in some declaration of printf
. Just not an entirely correct one.
Details: With MinGW g++ 7.3.0 the declaration/definition of printf
depends on the macro symbol __USE_MINGW_ANSI_STDIO
. The default is just that
declares printf
. But when __USE_MINGW_ANSI_STDIO
is defined as logical true,
provides an overriding definition of printf
, that calls __mingw_vprintf
. And as it happens the
header defines (via an indirect include) __USE_MINGW_ANSI_STDIO
before including
.
There is a comment in <_mingw.h>
, "Note that we enable it also for _GNU_SOURCE in C++, but not for C case.".
In C++, with relevant versions of this compiler, there is effectively a difference between including
and using printf
, or including
, saying using std::printf;
, and using printf
.
Regarding
” Also, how can it go until 55 decimal places? IEEE 754 floating point has only 52 bits for fractional number with which we can get 15 decimal digits of precision. It is stored in binary. How come its decimal interpretation stores more?
... it's just the decimal presentation that's longer. The digits beyond the precision of the internal representation, about 15 digits for 64-bit IEEE 754, are essentially garbage, but they can be used to reconstitute the original bits exactly. At some point they will become all zeroes, and that point is reached for the last digit in your C++ program output.
1Thanks to Dietrich Epp for finding that standards quote.