Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

drop trailing zeros from decimal

Tags:

python

decimal

I have a long list of Decimals and that I have to adjust by factors of 10, 100, 1000,..... 1000000 depending on certain conditions. When I multiply them there is sometimes a useless trailing zero (though not always) that I want to get rid of. For example...

from decimal import Decimal  # outputs 25.0,  PROBLEM!  I would like it to output 25 print Decimal('2.5') * 10  # outputs 2567.8000, PROBLEM!  I would like it to output 2567.8 print Decimal('2.5678') * 1000 

Is there a function that tells the decimal object to drop these insignificant zeros? The only way I can think of doing this is to convert to a string and replace them using regular expressions.

Should probably mention that I am using python 2.6.5

EDIT senderle's fine answer made me realize that I occasionally get a number like 250.0 which when normalized produces 2.5E+2. I guess in these cases I could try to sort them out and convert to a int

like image 446
b10hazard Avatar asked Jun 27 '12 13:06

b10hazard


People also ask

How do you get rid of trailing zero in decimals?

1. Using Decimal Numbers by Format Cells. First you have to select the cell in which you want to remove trailing zeros after the decimal point, right-click to the Format Cells from the context menu.

Do trailing zeros count if there is a decimal?

Trailing zeros (the right most zeros) are significant when there is a decimal point in the number. For this reason it is important to give consideration to when a decimal point is used and to keep the trailing zeros to indicate the actual number of significant figures.


2 Answers

There's probably a better way of doing this, but you could use .rstrip('0').rstrip('.') to achieve the result that you want.

Using your numbers as an example:

>>> s = str(Decimal('2.5') * 10) >>> print s.rstrip('0').rstrip('.') if '.' in s else s 25 >>> s = str(Decimal('2.5678') * 1000) >>> print s.rstrip('0').rstrip('.') if '.' in s else s 2567.8 

And here's the fix for the problem that gerrit pointed out in the comments:

>>> s = str(Decimal('1500')) >>> print s.rstrip('0').rstrip('.') if '.' in s else s 1500 
like image 33
Rod Hyde Avatar answered Sep 28 '22 02:09

Rod Hyde


You can use the normalize method to remove extra precision.

>>> print decimal.Decimal('5.500') 5.500 >>> print decimal.Decimal('5.500').normalize() 5.5 

To avoid stripping zeros to the left of the decimal point, you could do this:

def normalize_fraction(d):     normalized = d.normalize()     sign, digits, exponent = normalized.as_tuple()     if exponent > 0:         return decimal.Decimal((sign, digits + (0,) * exponent, 0))     else:         return normalized 

Or more compactly, using quantize as suggested by user7116:

def normalize_fraction(d):     normalized = d.normalize()     sign, digit, exponent = normalized.as_tuple()     return normalized if exponent <= 0 else normalized.quantize(1) 

You could also use to_integral() as shown here but I think using as_tuple this way is more self-documenting.

I tested these both against a few cases; please leave a comment if you find something that doesn't work.

>>> normalize_fraction(decimal.Decimal('55.5')) Decimal('55.5') >>> normalize_fraction(decimal.Decimal('55.500')) Decimal('55.5') >>> normalize_fraction(decimal.Decimal('55500')) Decimal('55500') >>> normalize_fraction(decimal.Decimal('555E2')) Decimal('55500') 
like image 165
senderle Avatar answered Sep 28 '22 01:09

senderle