Consider the following printf instruction:
printf("%# 01.1g", 9.8);
what should it print?
I'm reading the description of the g specifier on cppreference.com, which says (text for G removed):
converts floating-point number to decimal or decimal exponent notation depending on the value and the precision.
For the g conversion style conversion with style e or f will be performed.
Let P equal the precision if nonzero, 6 if the precision is not specified, or 1 if the precision is 0. Then, if a conversion with style e would have an exponent of X:
- if P > X ≥ −4, the conversion is with style f and precision P − 1 − X.
- otherwise, the conversion is with style e and precision P − 1.
Unless alternative representation is requested the trailing zeros are removed, also the decimal point character is removed if no fractional part is left.
In our case,
- P = 1 , specified explicitly.
- X = 0, since a "conversion with style e", i.e.
"%# 01.1e", yields9.8e+00(adjust the GodBolt program and you'll see). - 1 > 0 >= -4 holds.
consequently, the conversion should be with style f and precision P - 1 - X = 1 - 1 - 0 = 0, i.e. "%# 01.0f", which yields 10..
... but that is not what glibc produces: I get 1.e01, as can also be seen on GodBolt.
So,
- Am I mis-reading the quoted text?
- Is cppreference.com wrong?
- Is this - perish the tought - a glib 2.36 bug?
This is a lack of clarity about “a conversion with style
E” and a discrepancy about what the precision means forEandg.With
E, the precision is the number of digits to appear after the decimal point, per C 2018 7.21.6.1 4. Withg, the precision is the maximum number of significant digits. Those differ;Ehas an additional digit before the decimal point, giving a total of one more digit than its nominal “precision.”Thus, in considering how to format 9.8 for
%.1g, we first consider how it would be formatted for%.0E, not%.1E, as both%.1gand%.0Erequest one digit, whereas%.1Erequests two digits. For%.0E, “1e+01” would be produced. So the X, the exponent, is 1, not 0.