Search code examples
pythonpython-2.7decimalexponentscientific-notation

Can Decimal('5E+1') be simply converted to Decimal('50') in Python?


Context

We display percentage values to agents in our app without trailing zeros (50% is much easier to quickly scan than is 50.000%), and hitherto we've just used quantize to sort of brute force normalize the value to remove trailing zeros.

This morning I decided to look into using Decimal.normalize instead, but ran into this:

Given the decimal value:

>>> value = Decimal('50.000')

Normalizing that value:

>>> value = value.normalize()

Results in:

>>> value
Decimal('5E+1')

I understand the value is the same:

>>> Decimal('5E+1') == Decimal('50')
True

But from a non-technical user's perspective, 5E+1 is basically meaningless.

Question

Is there a way to convert Decimal('5E+1') to Decimal('50')?

Note

I'm not looking to do anything that would change the value of the Decimal (e.g., removing decimal places altogether), since the value could be e.g., Decimal('33.333'). IOW, don't confuse my 50.000 example as meaning that we're only dealing with whole numbers.


Solution

  • For the purposes of output formatting, you can print your normalized Decimal objects with the f format specifier. (While the format string docs say this defaults to a precision of 6, this does not appear to be the case for Decimal objects.)

    >>> print('{:f}%'.format(decimal.Decimal('50.000').normalize()))
    50%
    >>> print('{:f}%'.format(decimal.Decimal('50.003').normalize()))
    50.003%
    >>> print('{:f}%'.format(decimal.Decimal('1.23456789').normalize()))
    1.23456789%
    

    If for some reason, you really want to make a new Decimal object with different precision, you can do that by just calling Decimal on the f format output, but it sounds like you're dealing with an output format problem, not something you should change the internal representation for.

    >>> Decimal('{:f}'.format(Decimal('5E+1')))
    Decimal('50')
    >>> 
    >>> Decimal('{:f}'.format(Decimal('50.000').normalize()))
    Decimal('50')
    >>> Decimal('{:f}'.format(Decimal('50.003').normalize()))
    Decimal('50.003')
    >>> Decimal('{:f}'.format(Decimal('1.23456789').normalize()))
    Decimal('1.23456789')