Re: [Python-Dev] builtin round 2.7

2010-08-07 Thread Mark Dickinson
2010/8/7 Mark Dickinson :
> 2010/8/7 Kristján Valur Jónsson :
>> 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?
>
> 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.23001'.  If the round function hadn't been updated to
> be correctly rounded then this wouldn't be true.
> [...]

I should also point out that the pre-2.7 round function isn't
consistent across common platforms, so it was already dangerous to
rely on round results for halfway cases;  the 2.7 version of round
should be an improvement in that respect.  For example, with Python
2.6.6rc1 on OS X 10.6.4, I get the (correct) result:

>>> round(1.0007605, 6)
1.00076001

I'd expect to see the same result on OS X 10.5, on Windows and on
64-bit Linux boxes.  But on a 32-bit installation of Ubuntu maverick
(32-bit), I get the following instead:

>>> round(1.0007605, 6)
1.000761

The discrepancy is due to the usual problem of the x87 FPU computing
internally with 64-bit precision and then rounding the result to
53-bit precision afterwards, which can give different results from
computing directly using 53-bit precision.

Mark
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] builtin round 2.7

2010-08-07 Thread Mark Dickinson
2010/8/7 Kristján Valur Jónsson :
> 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.23001'.  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
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] builtin round 2.7

2010-08-07 Thread Kristján Valur Jónsson
Hi there.
I just hit a problem in my company, in the process of upgrading from stackless 
2.5 to 2.7.
Some rounding code, that was (foolishly) using "%.*f" string formatting to 
achieve floating point rounding started providing different results from 
before.  I explained this away to QA and Developement as a) you shouldn't do 
that, and b) string representation of floats became better and "more correct" 
in 2.7.  For UI rounding, I directed them to the Decimal module.

So far so good.

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?  I don't 
see this mentioned in the release notes and was initially a bit puzzled by it.  
Hasn't anyone else been hit by the discrepancy?

(and, yes, I know it is now more correct, as seen by round(5.55, 1)  (5.6 in 
py2.5, 5.5 in py 2.7 which is correct since 5.55 is actually 5.54... )

Perhaps the release notes need updating?

K


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com