Categories
floating-point precision python rounding

Limiting floats to two decimal points

2158

I want a to be rounded to 13.95. I tried using round:

>>> a
13.949999999999999
>>> round(a, 2)
13.949999999999999

11

  • 12

    Hmm… Are you trying to represent currency? If so, you should not be using floats for dollars. You could probably use floats for pennies, or whatever the smallest common unit of currency you’re trying to model happens to be, but the best practice is to use a decimal representation, as HUAGHAGUAH suggested in his answer.

    Apr 13, 2009 at 3:39

  • 82

    It is important not to represent currency in float. Floats are not precise. But penny or cent amounts are integers. Therefore integers are the correct way of representing currency.

    Jul 15, 2012 at 22:44

  • 4

    @Basic, it depends(mostly no). Using integers in cents, or pennies is fool prove. Its the industry standard of representing money. If you know what you are doing, have a sound understanding of floating point arithmetic and python’s decimal class, you might use decimal. But it depends much of your problem. Do you need arbitrary precision decimals? Or only two digits? If two digits: integer. It keeps you out of trouble. Source I worked in a software consultancy for banking.

    Apr 17, 2014 at 17:56

  • 30

    I’m coming probably too late here, but I wanted to ask, have the developers of Python solved this problem? Because when I do round(13.949999999999999, 2), I simply get 13.95. I’ve tried it in Python 2.7.6, as well as 3.4. It works. Not sure if 2.7 even was there in 2009. Maybe it’s a Python 2.5 thing?

    Sep 22, 2015 at 5:51


  • 8

    @bad_keypoints: Yes, the rounding problem has been solved by by Python 2.7.0+. More in my answer here

    – hynekcer

    Jul 29, 2016 at 17:55

741

There are new format specifications, String Format Specification Mini-Language:

You can do the same as:

"{:.2f}".format(13.949999999999999)

Note 1: the above returns a string. In order to get as float, simply wrap with float(...):

float("{:.2f}".format(13.949999999999999))

Note 2: wrapping with float() doesn’t change anything:

>>> x = 13.949999999999999999
>>> x
13.95
>>> g = float("{:.2f}".format(x))
>>> g
13.95
>>> x == g
True
>>> h = round(x, 2)
>>> h
13.95
>>> x == h
True

8

  • 23

    to add commas as well you can '{0:,.2f}'.format(1333.949999999) which prints '1,333.95'.

    Jun 20, 2014 at 2:41


  • @OnurYıldırım: yes, but you can wrap it with float(); float("{0:.2f}".format(13.9499999))

    Aug 17, 2014 at 13:22


  • 5

    @JossefHarush you can wrap it with float(), but you haven’t gained anything. Now you have a float again, with all the same imprecision. 13.9499999999999 and 13.95 are the same float.

    Aug 17, 2014 at 13:52

  • 4

    @NedBatchelder: i agree that they are equal, but this limits the float to two decimal points 🙂

    Aug 17, 2014 at 14:09


  • 47

    By the way, since Python 3.6 we can use f-strings: f"Result is {result:.2f}"

    Feb 20, 2019 at 12:54

384

The built-in round() works just fine in Python 2.7 or later.

Example:

>>> round(14.22222223, 2)
14.22

Check out the documentation.

6

  • 1

    So am I to understand that this is a Python 2.7 fail? Why would such a fundamental function yield different results from v 2.7 to v 3?

    Sep 2, 2017 at 23:50


  • 1

    but round(2.16, 1) give 2.2 why python just offer a truncate func

    – jiamo

    Jan 8, 2018 at 3:31


  • 1

    For example, if you try to round the value 2.675 to two decimal places, you get this >>> round(2.675, 2) 2.67 docs.python.org/2/tutorial/floatingpoint.html

    Nov 6, 2018 at 17:41


  • 7

    From Python 3 documentation page: Note The behavior of round() for floats can be surprising: for example, round(2.675, 2) gives 2.67 instead of the expected 2.68. This is not a bug: it’s a result of the fact that most decimal fractions can’t be represented exactly as a float.

    May 18, 2019 at 22:14


  • 2

    Note that if you try to use this method to print out a number such as 1.00000 it will only print out 1.0, regardless of how many decimal points you specify.

    Aug 3, 2019 at 16:36