views:

13673

answers:

6

I want a to be rounded to 13.95

>>> a
13.949999999999999


>>> round(a, 2)
13.949999999999999

The round function does not work [the way I expect].

+20  A: 

You are running into the old problem with floating point numbers that all numbers cannot be represented. The command line is just showing you the full floating point form from memory. In floating point your rounded version is the same number. Since computers are binary they store floating point numbers as an integer and then divide it by a power of two so 13.95 will be represented in a similar fashion to 125650429603636838/(2**53). Double precision numbers have 53 bits (16 digits) of precision and regular floats have 24 bits (8 digits) of precision. The floating point in python uses double precision to store the values.

for example

  >>>125650429603636838/(2**53)
  13.949999999999999

  >>> 234042163/(2**24)
  13.949999988079071

  a=13.946
  print(a)
  13.946
  print("%.2f" % a)
  13.95
  round(a,2)
  13.949999999999999
  print("%.2f" % round(a,2))
  13.95

If you are after only two decimal places as in currency then you have a couple of better choices use integers and store values in cents not dollars and then divide by 100 to convert to dollars. Or use a fixed point number like decimal

Rex Logan
+5  A: 

What you can do is modify the output format:

>>> a = 13.95
>>> a
13.949999999999999
>>> print "%.2f" % a
13.95
Greg Hewgill
+4  A: 

It's doing exactly what you told it to do, and working correctly. Read more about floating point confusion and maybe try Decimal objects instead.

HUAGHAGUAH
+7  A: 

Most numbers cannot be exactly represented in floats. If you want to round the number because that's what your mathematical formula or algorithm requires, then you want to use round. If you just want to restrict the display to a certain precision, then don't even use round and just format it as that string. (If you want to display it with some alternate rounding method, and there are tons, then you need to mix the two approaches.)

>>> "%.2f" % 3.14159
'3.14'
>>> "%.2f" % 13.9499999
'13.95'

And lastly, though perhaps most importantly, if you want exact math then you don't want floats at all. The usual example is dealing with money and to store 'cents' as an integer.

Roger Pate
+3  A: 

The python tutorial has an appendix called: Floating Point Arithmetic: Issues and Limitations. Read it. It explains what is happening and why python is doing its best. It has even an example that matches yours. Let me quote a bit:

>>> 0.1
0.10000000000000001

you may be tempted to use the round() function to chop it back to the single digit you expect. But that makes no difference:

>>> round(0.1, 1)
0.10000000000000001

The problem is that the binary floating-point value stored for “0.1” was already the best possible binary approximation to 1/10, so trying to round it again can’t make it better: it was already as good as it gets.

Another consequence is that since 0.1 is not exactly 1/10, summing ten values of 0.1 may not yield exactly 1.0, either:

>>> sum = 0.0
>>> for i in range(10):
...     sum += 0.1
...
>>> sum
0.99999999999999989

One alternative and solution to your problems would be using the decimal module.

nosklo
A: 

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.

TokenMacGuy