How to convert float to fixed point decimal in python

11,832

Use Decimal.quantize:

Return a value equal to the first operand after rounding and having the exponent of the second operand.

>>> from decimal import Decimal
>>> Decimal(50.15)
Decimal('50.14999999999999857891452847979962825775146484375')
>>> Decimal(50.15).quantize(Decimal('1.00'))
Decimal('50.15')

Unlike the bad str approach, this works for any number:

>>> decimal.Decimal(str(50.0))
Decimal('50.0')
>>> decimal.Decimal(50.0).quantize(decimal.Decimal('1.00'))
Decimal('50.00')
Share:
11,832
balki
Author by

balki

A computer enthusiast.

Updated on June 04, 2022

Comments

  • balki
    balki almost 2 years

    I have some library function foo, that returns a floating point value with two decimal places (representing a price). I have to pass to to other function bar which expects a Decimal with fixed point for two decimal places.

    value = foo() # say value is 50.15
    decimal_value = decimal.Decimal(value) # Not expected. decimal_value contains Decimal('50.14999999999999857891452847979962825775146484375')
    bar(decimal_value) # Will not work as expected
    
    # One possible solution
    value = foo() # say value is 50.15
    decimal_value = decimal.Decimal(str(round(value,2))) # Now decimal_value contains Decimal('50.15') as expected
    bar(decimal_value) # Will work as expected
    

    Question:

    How to convert arbitrary float to fixed Decimal point with 2 decimal places? And without intermediate string conversion using str.

    I am not worried about the performance. Just want to confirm if intermediate str conversion is the pythonic way.

    Update: Other Possible Solutions

    # From selected answer
    v = 50.15
    d = Decimal(v).quantize(Decimal('1.00'))
    
    # Using round (Does not work in python2)
    d = round(Decimal(v), 2)
    
    • Mark Dickinson
      Mark Dickinson almost 7 years
      I like the round solution, as its easier to read and write than the quantize-base solution. But bear in mind it only works on Python 3: on Python 2, rounding a Decimal instance gives a float back.
    • balki
      balki almost 7 years
      Thanks! Edited to make a note.
  • Christian Dean
    Christian Dean almost 7 years
    But why not just str? Is there a compelling reason to user Decimal.quantize over str?
  • Antti Haapala -- Слава Україні
    Antti Haapala -- Слава Україні almost 7 years
    @ChristianDean because str is not guaranteed to give 2 decimal places.
  • Christian Dean
    Christian Dean almost 7 years
    Ah, I see. I didn't know that.