I have a doubt concerning the output of the following C program. I tried to compile it using both Visual C++ 6.0 and MinGW32 (gcc 3.4.2).
#include
This is certainly a compiler bug. From the C11 standard we have the following guarantees (C99 was similar):
float
are also representable by double
(6.2.5/10)float
to double
does not change the value (6.3.1.5/1)int
to float
, when the int value is in the set of representable values for float
, gives that value. int
to float
, when the magnitude of the int value is less than FLT_MAX
and the int
is not a representable value for float
, causes either the next-highest or next-lowest float
value to be selected, and which one is selected is implementation-defined. (6.3.1.4/2)The third of these points guarantees that the float
value supplied to printf
is not modified by the default argument promotions.
If 2147483647
is representable in float
, then (float)x
and (float)2147483647
must give 2147483647.000000
.
If 2147483647
is not representable in float
, then (float)x
and (float)2147483647
must either give the next-highest or next-lowest float
. They don't both have to make the same selection. But this means that a printout of 2147483647.000000
is not permitted1, each must either be the higher value or the lower value.
1 Well - it's theoretically possible that the next-lowest float was 2147483646.9999999...
so when the value is displayed with 6-digit precision by printf
then it is rounded to give what was seen. But this isn't true in IEEE754 and you could easily experiment to discount this possibility.