Why does %e behave different than %g in format strings?

Question:

I have tried this in Python2, Python3 and C:

Why do these format string return numbers with different precision?

>>> "%.3e" % 123456789
'1.235e+08' 
>>> "%.3g" % 123456789
'1.23e+08' 
Asked By: steffen

||

Answers:

From the Python 3.7 documentation:

'e':

Exponent notation. Prints the number in scientific notation using the letter ‘e’ to indicate the exponent. The default precision is 6.

'g':

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, unless the '#' option is used.

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.

With alternative values:

>>> "%.3e" % 123
'1.230e+02'
>>> "%.3g" % 123
'123'
>>> "%.3e" % 1234
'1.234e+03'
>>> "%.3g" % 1234
'1.23e+03'

The difference then is clearly about how the precision is specified. g appears to use the precision as the normal definition of precision, whereas e uses the number of figures after the decimal point.

Answered By: Dale Myers

From the printf(3) man page:

e, E

The double argument is rounded and converted in the style [-]d.ddde±dd where there is one digit before the decimal-point character and the number of digits after it is equal to the precision; if the precision is missing, it is taken as 6; if the precision is zero, no decimal-point character appears. An E conversion uses the letter E (rather than e) to introduce the exponent. The exponent always contains at least two digits; if the value is zero, the exponent is 00.

g, G

The double argument is converted in style f or e (or F or E for G conversions). The precision specifies the number of significant digits. If the precision is missing, 6 digits are given; if the precision is zero, it is treated as 1. Style e is used if the exponent from its conversion is less than -4 or greater than or equal to the precision. Trailing zeros are removed from the fractional part of the result; a decimal point appears only if it is followed by at least one digit.

So, they do different things even with the same precision.

I will try to describe the rules for %g first.

I found @Dale Myers ‘s quoted docs very much tells the details already, I suggest take a look at it, but I will give a more clear explanation here.

Exponent and Precision

Before we start talking about the rules, let’s make it clear the meaning for the words exp (the Exponent used in the scientific notation) and precision (will be shorted as p, it is the precision used in the formatting expression, %.6e or %.6g. Precision is default to 6).

Rules for general format

OK, here goes the rules for %g (general format):

  • -4 <= exp < p: use the decimal format
  • exp < -4: use the exponential format
  • exp >= p: use the exponential format
  • the result will be rounded when calculating the precision digits.
  • the precision is used to restrict all digits not just for decimal digits.

Let’s see all the edge cases below:

>>> gx = '%.6g'
>>> ex = '%.6e'
# -4 <= exp < p
>>> gx % 12345
12345
>>> gx % 0.012345
0.012345
# exp == p
>>> ex % 1234567
1.23456e+06
>>> gx % 1234567
1.23457e+06 # Notic the decimal digits are rounded
# exp == -4
>>> ex % 0.000123456
1.234560e-4
>>> gx % 0.000123456
0.000123456
# exp < -4
>>> ex % 0.0000123456
1.234560e-5
>>> gx % 0.0000123456
1.23456e-5

Why we need %g

If you now understand the rules for %g, it is quite clear that it tries to find a middle ground between %f and e, so that when formatting numbers, it will use the most appropriate format for you instead of deciding %f or %e by yourself.

Answered By: Neekey
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.