%g
, %G
precision specificationThis issue has been automatically converted from the original issue lists and some formatting may not have been preserved.
Authors: Chris Torek, Project Editor (Larry Jones)
Date: 2000-04-24
Submitted against: C99
Status: Fixed
Fixed in: C99 TC2
Converted from: summary-c99.htm, dr_233.htm
7.19.6.1 (and similarly in 7.24.2.1):
g,G
A
double
argument representing a floating-point number is converted in stylef
ore
(or in styleF
orE
in the case of aG
conversion specifier), with the precision specifying the number of significant digits. If the precision is zero, it is taken as 1. The style used depends on the value converted; stylee
(orE
) is used only if the exponent resulting from such a conversion is less than -4 or greater than or equal to the precision. Trailing zeros are removed from the fractional portion of the result unless the#
flag is specified; a decimal-point character appears only if it is followed by a digit.A
double
argument representing an infinity or NaN is converted in the style of anf
orF
conversion specifier.
Assuming "significant digits" is being used in the scientific-notation sense. This means that, for instance, the number "12.34" has four significant digits. So does "0.1234", and so does "0.001234". A value like "1.200" also has four significant digits, counting trailing zeros, but not leading zeros.
Now, %g
normally suppresses trailing zeros (as described above), so applying
%.4g
to the value 1.2 produces not "1.200" but rather just "1.2". The #
modifier, however, stops the trailing-zero suppression, and:
printf("%#.4g\n", 1.2);
must produce "1.200", four significant digits.
The problem occurs when we go to print the value 0.0. No matter how many digits we tack on the end, we still have no significant digits. So what should:
printf("%#.4g\n", 0.0);
print? "0.0000" has no significant digits. "0.0" has no significant digits. "0.000000000000000000000000000000000000000" still has no significant digits. Which of these, if any, is correct output? Which of these is desirable output?
The only way this wording makes any sense is if "significant digits" means something else entirely, but then what does it mean?
Comment from WG14 on 2007-09-07:
There seemed to be some uncertainty about whether (for the %.4g
example) the
exponent would be 0
or 1
. This could yield different results.
Some Committee members wondered whether the exponent would be 1
or 0
for
ZERO. The bullet describing e, E
is clear on this though "If the value is
zero, the exponent is zero".
If there is no implementation representation of ZERO, but rather a very small number. In this case, we generally thought that this was a user problem, that they could not rely on a true ZERO having a representation, in which case, they would need to place their own checks for what approximations were acceptable as ZERO and print a literal instead.
Some pathological cases were checked, and appeared to work correctly.
NOTE: In discussion, the original bullets were:
But these were changed to:
During discussion, as it was considered to be the more pure form.
Comment from WG14 on 2007-09-07:
Change 7.19.6.1 paragraph 8 and 7.24.2.1 paragraph 8 to:
g,G
A
double
argument representing a floating-point number is converted in stylef
ore
(or in styleF
orE
in the case of aG
conversion specifier), depending on the value converted and the precision. LetP
equal the precision if non-zero, 6 if the precision is omitted, or 1 if the precision is zero. Then, if a conversion with styleE
would have an exponent ofX
:
- if
P > X >= -4
, the conversion is with stylef
(orF
) and precisionP - (X + 1)
.- otherwise the conversion is with style
e
(orE
) and precisionP - 1
.Finally, unless the
#
flag is used, any trailing zeroes are removed from the fractional portion of the result and the decimal-point character is removed if there is no fractional portion remaining.