views:

7104

answers:

10

The documentation for the round() function states that you pass it a number, and the positions past the decimal to round. Thus is should do this:

n = 5.59
round(n, 1) # 5.6

But, in actuality, good old floating point weirdness creeps in and you get:

5.5999999999999996

For the purposes of UI, I need to display '5.6'. I poked around the Internet and found some documentation that this is dependent on my implementation of Python. Unfortunately, this occurs on both my Windows dev machine and each Linux server I've tried. See here also.

Short of creating my own round library, is there any way around this?

Update: Ok, string formatting. Sometimes, it's just a really simple answer. Thanks everyone.

A: 

round(n,1)+epsilon

ima
+17  A: 

can't help the way it's stored, but at least formatting works correctly:

'%.1f' % round(n, 1) gives you '5.6'
Jimmy
For my purposes, that's all I need. Thank you!
swilliams
A: 

You can switch the data type to a integer:

>>> n = 5.59
>>> int(n * 10) / 10.0
5.5
>>> int(n * 10 + 0.5) 
56

And then display the number by inserting the locale's decimal separator.

However, Jimmy's answer is better.

Frank Krueger
+1  A: 

You can use the string format operator %, similar to sprintf.

mystring = "%.2f" % 5.5999
nlucaroni
+1  A: 

You get '5.6' if you do str(round(n, 1)) instead of just round(n, 1).

Tomi Kyöstilä
+3  A: 

Floating point math is vulnerable to slight, but annoying, precision inaccuracies. If you can work with integer or fixed point, you will be guaranteed precision.

spoulson
A: 

printf the sucker.

print '%.1f' % 5.59  # returns 5.6
Jason Navarrete
+4  A: 

Formatting works correctly even without having to round:

"%.1f" % n

Vinko Vrsalovic
+3  A: 

round(5.59, 1) is working fine. The problem is that 5.6 cannot be represented exactly in binary floating point.

>>> 5.6
5.5999999999999996
>>>

As Vinko says, you can use string formatting to do rounding for display.

Python has a module for decimal arithmetic if you need that.

Will Harris
+1  A: 

Take a look at the Decimal module

Decimal “is based on a floating-point model which was designed with people in mind, and necessarily has a paramount guiding principle – computers must provide an arithmetic that works in the same way as the arithmetic that people learn at school.” – excerpt from the decimal arithmetic specification.

and

Decimal numbers can be represented exactly. In contrast, numbers like 1.1 and 2.2 do not have an exact representations in binary floating point. End users typically would not expect 1.1 + 2.2 to display as 3.3000000000000003 as it does with binary floating point.

Decimal provides the kind of operations that make it easy to write apps that require floating point operations and also need to present those results in a human readable format, e.g., accounting.

Jesse Dhillon