drop trailing zeros from decimal

前端 未结 9 1901
庸人自扰
庸人自扰 2020-11-29 03:54

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

相关标签:
9条回答
  • 2020-11-29 04:34

    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')
    
    0 讨论(0)
  • 2020-11-29 04:36

    Why not use modules 10 from a multiple of 10 to check if there is remainder? No remainder means you can force int()

    if (x * 10) % 10 == 0:
        x = int(x)
    

    x = 2/1
    Output: 2

    x = 3/2
    Output: 1.5

    0 讨论(0)
  • 2020-11-29 04:39

    I ended up doing this:

    import decimal
    
    def dropzeros(number):
        mynum = decimal.Decimal(number).normalize()
        # e.g 22000 --> Decimal('2.2E+4')
        return mynum.__trunc__() if not mynum % 1 else float(mynum)
    
    print dropzeros(22000.000)
    22000
    print dropzeros(2567.8000)
    2567.8
    

    note: casting the return value as a string will limit you to 12 significant digits

    0 讨论(0)
提交回复
热议问题