Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python rounding issue

I have come across a very strange issue in python. (Using python 2.4.x)

In windows:

>>> a = 2292.5
>>> print '%.0f' % a
2293

But in Solaris:

>>> a = 2292.5
>>> print '%.0f' % a
2292

But this is the same in both windows and solaris:

>>> a = 1.5
>>> print '%.0f' % a
2

Can someone explain this behavior? I'm guessing it's platform dependent on the way that python was compiled?

like image 227
John Jiang Avatar asked Feb 01 '10 00:02

John Jiang


People also ask

How do I fix rounding in Python?

If you first take the absolute value of n using Python's built-in abs() function, you can just use round_half_up() to round the number. Then all you need to do is give the rounded number the same sign as n .

Why does Python have rounding errors?

This is because the floating point can not be represented by the exact number, it is just approximation, and when it is used in arithmetic, it is causing a small error. Another example shows below that 0.1 + 0.2 + 0.3 is not equal 0.6, which has the same cause.

How do you fix rounding errors?

Increasing the number of digits allowed in a representation reduces the magnitude of possible roundoff errors, but any representation limited to finitely many digits will still cause some degree of roundoff error for uncountably many real numbers.

Why does 2.5 round down in Python?

Also, if the number is of the form x. 5 , then, the values will be rounded up if the roundup value is an even number. Otherwise, it will be rounded down. For example, 2.5 will be rounded to 2, since 2 is the nearest even number, and 3.5 will be rounded to 4.


2 Answers

The function ultimately in charge of performing that formatting is PyOS_snprintf (see the sources). As you surmise, that's unfortunately system-dependent, i.e., it relies on vsprintf, vsnprintf or other similar functions that are ultimately supplied by the platform's C runtime library (I don't recall if the C standard says anything about the '%f' formatting for floats that are "exactly midway" between two possible rounded values... but, whether the C standard is lax about this, or rather the C standard is strict but some C runtimes break it, ultimately is a pretty academic issue...).

like image 159
Alex Martelli Avatar answered Oct 22 '22 03:10

Alex Martelli


round() rounds toward the nearest even integer
"%n.nf" works the same way as round()
int() truncates towards zero

"rounding a positive number to the nearest integer
can be implemented by adding 0.5 and truncating"
-- http://en.wikipedia.org/wiki/Rounding

In Python you can do this with: math.trunc( n + 0.5 )
assuming n is positive of course...

Where "round half to even" is not appropriate, i now use
math.trunc( n + 0.5 ) where i used to use int(round(n))

like image 41
jh45dev Avatar answered Oct 22 '22 04:10

jh45dev