How `G` type of python % string formatting behave?

Viewed 152

I read:

The g and G conversion types choose between floating point or exponential output, depending on the magnitude of the exponent and the value specified for .<precision>. Output is the same as e/E if the exponent is less than -4 or not less than .<precision>. Otherwise, it’s the same as f/F:

Also, I didnt get "if the exponent is less than -4 or not less than .<precision>". Where do we specify exponent explicitly? By "exponent", does it mean number of digits after decimal point? I feel so, as when I tried to have four digits after decimal points, it printed it as f, but when I tried having five digits after decimal points, it printed it as e:

>>> '%g' % 0.0003
'0.0003'
>>> '%g' % 0.00003
'3e-05'

Q1. Am I correct with above understanding?

Q2. But, then, I didnt get why it did not do same in below example:

>>> '%g' % 3.14
'3.14'
>>> '%g' % 3.014
'3.014'
>>> '%g' % 3.0014
'3.0014'
>>> '%g' % 3.00014
'3.00014'
>>> '%g' % 3.000014
'3.00001'
>>> '%g' % 3.0000014
'3'

Q3. Finally, I didnt get "or not less than .<precision>" part of "if the exponent is less than -4 or not less than .<precision>". I tried to explicitly specify precision less than and more than 4 digits after decimal point. But it still printed the same:

>>> '%g' % 0.00003
'3e-05'
>>> '%.3g' % 0.00003
'3e-05'
>>> '%.9g' % 0.00003
'3e-05'
2 Answers

By "exponent", does it mean number of digits after decimal point?

No. Exponent is simply speaking number you get after e in notation, for example 0.999 might be rendered as 9.990000e-01 which mean exponent of 0.999 is -1. Exponent value does inform about order of magnitude.

As per C11 standard:

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.

A double argument representing an infinity or NaN is converted in the style of an f or F conversion specifier.

Also from Python documentation another description of the same behaviour is:

General format. For a given precision p >= 1, this rounds the number to p significant digits and then formats the result in either fixed-point format or in scientific notation, depending on its magnitude.

The precise rules are as follows: suppose that the result formatted with presentation type 'e' and precision p-1 would have exponent exp. Then if -4 <= exp < p, the number is formatted with presentation type 'f' and precision p-1-exp. Otherwise, the number is formatted with presentation type 'e' and precision p-1. In both cases insignificant trailing zeros are removed from the significand, and the decimal point is also removed if there are no remaining digits following it.

Positive and negative infinity, positive and negative zero, and nans, are formatted as inf, -inf, 0, -0 and nan respectively, regardless of the precision.

A precision of 0 is treated as equivalent to a precision of 1. The default precision is 6.

Related