[Python-Dev] builtin round 2.7

Mark Dickinson dickinsm at gmail.com
Sat Aug 7 12:58:39 CEST 2010


2010/8/7 Kristján Valur Jónsson <kristjan at ccpgames.com>:
> Hi there.
> [...]
> But it appears that the builtin round() method also changed.  Whereas I see
> the changing of floating point representation in string formatting as not
> being very serious, why did the arithmetic function round() have to change?

This was part of the short float repr changes that were backported
from 3.1.  The round function in 2.7 (on most platforms; barring bugs)
always gives correctly rounded results; in 2.6 it was a bit less
predictable in halfway cases.

One reason to want round to be correctly rounded is to ensure that the
repr of the result is always the 'short' one;  this means that
repr(round(x, 2)) will never produce results like
'0.23000000000000001'.  If the round function hadn't been updated to
be correctly rounded then this wouldn't be true.

Another reason is to make sure that string formatting and the round
function finally agree with each other:  both are doing the same job
of rounding to some nearest decimal representation (except that one
returns a float, while the other returns a string), so the results
should be comparable;  the discrepancy between these two operations
has confused users in the past.  Unfortunately, the agreement isn't
quite complete, since round in 2.7 continues to use
round-half-away-from-zero for actual exact halfway cases, while string
formatting uses round-half-to-even (so e.g. round(0.125, 2) gives (a
binary approximation to) 0.13, while format(0.125, '.2f') gives
'0.12').  In 3.x they both use round-half-to-even.

The only place where people are likely to notice that the round result
has changed is in halfway cases, for example round(12.385, 2) (which,
of course, thanks to the usual binary floating-point issues, is only
actually an approximation to a halfway case).  In general, if you're
expecting predictable results from *decimal* rounding of *binary*
approximations to *decimal* halfway cases then you're asking for
trouble.  For predictable rounding, use the decimal module.

I recently added some text to the floating-point section of the 2.7
tutorial to help explain these round problems.

> I don‘t see this mentioned in the release notes and was initially a bit
> puzzled by it.

True;  I don't see it in the whatsnew document either.  It's in
Misc/NEWS, though.  (Search for Issue 7117;  there are several
entries).

Mark


More information about the Python-Dev mailing list