tags:

views:

219

answers:

3

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?

A: 

I is plataform dependent. You can find the documentation here.

It is good to user ceil or floor when you know what you want (to round up or down).

Flávio Amieiro
+10  A: 

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...).

Alex Martelli
I believe that some implementations (of C) round down when the previous digit is even and round up when it is odd
gnibbler
gnibbler - you just blew my mind
PCBEEF
@gnibbler, that's a good accounting rule (even mandated by law in some jurisdictions, I think) -- but then accounting is invariably performed with decimal-based numbers, **not** binary floats, so in the context of floats this becomes somewhat moot;-).
Alex Martelli
I think the C standard mandates ISO 754, but that specifies several possible rounding modes (probably so as not to break existing FPU rounding hardware), two of which are "round to even" (glibc) and "round away from 0" (Windows CRT). See http://en.wikipedia.org/wiki/Floating_point#Rounding_modes. "Round to even" is weird and pointless, but it's legal and we're stuck with it.
Glenn Maynard
It's not weird and pointless. That rule means that on average all your roundings even out.
Lennart Regebro
Only if the second-least significant digit of all your numbers are uniformly distributed between odd and even. I may be misunderstanding Benford's Law, but I'm pretty sure that's rarely the case.
detly
A: 

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))

jh45dev