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.
Is there a way to convert Decimal('5E+1')
to Decimal('50')
?
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.
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')