Skip to content

Instantly share code, notes, and snippets.

@jackiekazil
Last active January 17, 2024 12:29
Show Gist options
  • Save jackiekazil/6201722 to your computer and use it in GitHub Desktop.
Save jackiekazil/6201722 to your computer and use it in GitHub Desktop.
How do I round to 2 decimals in python?

How do I round to 2 decimals?

In python, you have floats and decimals that can be rounded. If you care about the accuracy of rounding, use decimal type. If you use floats, you will have issues with accuracy.

All the examples use demical types, except for the original value, which is automatically casted as a float.

To set the context of what we are working with, let's start with an original value.

Original Value

print 16.0/7

Output: 2.2857142857142856

1: Round decimal using round()

from decimal import Decimal

# First we take a float and convert it to a decimal
x = Decimal(16.0/7)

# Then we round it to 2 places
output = round(x,2)
print output

Output: 2.29

2: Round decimal with super rounding powers

from decimal import Decimal, ROUND_HALF_UP
# Here are all your options for rounding:
# This one offers the most out of the box control
# ROUND_05UP       ROUND_DOWN       ROUND_HALF_DOWN  ROUND_HALF_UP
# ROUND_CEILING    ROUND_FLOOR      ROUND_HALF_EVEN  ROUND_UP

our_value = Decimal(16.0/7)
output = Decimal(our_value.quantize(Decimal('.01'), rounding=ROUND_HALF_UP))

print output

Output: 2.29

3: Round decimal by setting precision

# If you use deimcal, you need to import
from decimal import getcontext, Decimal

# Set the precision.
getcontext().prec = 3

# Execute 1/7, however cast both numbers as decimals
output = Decimal(16.0)/Decimal(7)

# Your output will return w/ 6 decimal places, which
# we set above.
print output

Output: 2.29

In example 3, if we set the prec to 2, then we would have 2.3. If we set to 6, then we would have 2.28571.

Solution

Which approach is best? They are all viable. I am a fan of the second option, because it offers the most control. If you have a very specific use case (i.e. 2010 WMATA practice rounding habits of up and down to the .05 depending on the fare), you may have to customize this part in your code.

@Mec-iS
Copy link

Mec-iS commented Dec 18, 2018

Decimal has a quite high impact on performances:

In [12]: timeit.timeit("round(7.325, 2)")
Out[12]: 0.39438656000129413

In [9]: timeit.timeit("from decimal import Decimal, ROUND_DOWN;round(Decimal('7.325'), 2)")
Out[9]: 0.9643819720076863

In [21]: timeit.timeit("float('%.2f' % 7.325)")
Out[21]: 0.3827699579996988

@rblack
Copy link

rblack commented Feb 19, 2019

@Mec-iS While Decimal is indeed slower, I believe your example is not totally correct. You measure imports together with initializing Decimal object. IMO timeit.timeit(stmt="round(d, 2)", setup="from decimal import Decimal, ROUND_DOWN;d=Decimal('7.325')") would be closer analog of rounding floats.

@weaming
Copy link

weaming commented Oct 15, 2019

Slow but correct, I choose Decimal .

@HeyHugo
Copy link

HeyHugo commented Nov 8, 2019

Money class method from py-moneyed:

def round(self, ndigits=0):
    """
    Rounds the amount using the current ``Decimal`` rounding algorithm.
    """
    if ndigits is None:
        ndigits = 0
    return self.__class__(
        amount=self.amount.quantize(Decimal('1e' + str(-ndigits))),
        currency=self.currency
    )

@orrinstimpson
Copy link

python has a built in round function that allows you to specify the number of decimals to truncate too. See https://stackoverflow.com/questions/455612/limiting-floats-to-two-decimal-points

@mhihasan
Copy link

mhihasan commented Apr 3, 2021

A

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment