Floating point "g" format not stripping trailing zeros

Hrvoje Nikšić hniksic at gmail.com
Fri Feb 13 04:26:35 EST 2015


Ian Kelly writes:
> When you specify the a precision of 15 in your format string, you're
> telling it to take the first 15 of those. It doesn't care that the
> last couple of those are zeros, because as far as it's concerned,
> those digits are significant.

OK, it's a bit surprising, but also consistent with the rest of the
decimal module. Thanks for clearing it up.

My concrete use case is printing an arbitrary fraction as a
user-readable decimal, rounded to the specified number of digits, and
using the exponential notation where appropriate:

import decimal
_dec_fmt_context = decimal.Context(prec=15, rounding=decimal.ROUND_HALF_UP)
def _format(frac):
    with decimal.localcontext(_dec_fmt_context):
        dec = decimal.Decimal(frac.numerator) /
decimal.Decimal(frac.denominator)
        return '{:g}'.format(dec)

The decimal obtained by dividing the numerator with the denominator
includes trailing zeros. Calling normalize() to get rid of them will
have the unfortunate side effect of turning 9806650 into 9.80665e+6,
and the method recommended in the documentation:

def remove_exponent(d):
    return d.quantize(decimal.Decimal(1)) if d == d.to_integral() else
d.normalize()

...will raise "decimal.InvalidOperation: quantize result has too many
digits for current context" when the number is too large. For now I'm
emulating the behavior of '%g' on floats using rstrip('0') to get rid
of the trailing zeros:

    ...
        s = '{:g}'.format(dec)
    if '.' in s and 'e' not in s:
        s = s.rstrip('0')
        s = s.rstrip('.')
    return s



More information about the Python-list mailing list