Why this happens?
I tested:
double f = 101.9716;
printf("%f
", f);
printf("%e
", f);
printf("%g
", f);
And it output:
101.971600
1.019716e+02 // Notice the exponent +02
101.972
Here's what C standard (N1570 7.21.6.1) says about conversion specifier g
:
A double
argument representing a floating-point number is converted in
style f
or e
(or in style F
or E
in the case of a G conversion specifier), depending on the value converted and the precision. Let P equal the precision if nonzero, 6 if the precision is omitted, or 1 if the precision is zero. Then, if a conversion with style E
would have an exponent of X:
— if P > X ≥ ?4, the conversion is with style f
(or F
) and precision
P ? (X + 1).
— otherwise, the conversion is with style e
(or E
) and precision P ? 1.
So given above, P will equal 6, because precision is not specified, and X will equal 2, because it's the exponent on style e
.
Formula 6 > 2 >= -4 is thus true, and style f
is selected. And precision will then be 6 - (2 + 1) = 3.
How to fix?
Unlike f
, style g
will strip unnecessary zeroes, even when precision is set.
Finally, unless the #
flag is used, any trailing zeros are removed from the fractional portion of the result and the decimal-point character is removed if there is no fractional portion remaining.
So set high enough precision:
printf("%.8g
", f);
prints:
101.9716
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…