This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: rounding error in % operator
Type: behavior Stage: resolved
Components: Versions: Python 2.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: William McIlhagga, mark.dickinson
Priority: normal Keywords:

Created on 2016-11-16 20:10 by William McIlhagga, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (5)
msg280984 - (view) Author: William McIlhagga (William McIlhagga) Date: 2016-11-16 20:10
'%.1f' % 0.25          yields the string '0.2'

'%.1f' % 0.75          yields the string '0.8'

This is wrong.
msg280994 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2016-11-16 21:37
You don't say why you think this behaviour is wrong, or what you'd expect to see instead.

Nevertheless, this behaviour is by design: the code `'%.1f' % x` rounds `x` to the nearest one-digit-after-the-point decimal number, and returns a string representation of that number. In the case `x=0.25`, there is no single nearest number: `0.2` and `0.3` are equally close to `0.25`, so a choice between the two has to be made. In keeping with many other languages, Python chooses the value with even last digit. (The original behaviour is inherited from the typical behaviour of the standard library strtod or dtoa functions in C.)
msg280996 - (view) Author: William McIlhagga (William McIlhagga) Date: 2016-11-16 21:53
OK, not wrong, just unexpected.

Is this behaviour documented? Or are you just expected to know what C does?

On 16 November 2016 at 21:37, Mark Dickinson <report@bugs.python.org> wrote:

>
> Mark Dickinson added the comment:
>
> You don't say why you think this behaviour is wrong, or what you'd expect
> to see instead.
>
> Nevertheless, this behaviour is by design: the code `'%.1f' % x` rounds
> `x` to the nearest one-digit-after-the-point decimal number, and returns a
> string representation of that number. In the case `x=0.25`, there is no
> single nearest number: `0.2` and `0.3` are equally close to `0.25`, so a
> choice between the two has to be made. In keeping with many other
> languages, Python chooses the value with even last digit. (The original
> behaviour is inherited from the typical behaviour of the standard library
> strtod or dtoa functions in C.)
>
> ----------
> nosy: +mark.dickinson
> resolution:  -> not a bug
> stage:  -> resolved
> status: open -> closed
>
> _______________________________________
> Python tracker <report@bugs.python.org>
> <http://bugs.python.org/issue28717>
> _______________________________________
>

-- 
Dr. William McIlhagga
Bradford School of Optometry & Vision Science,
Bradford University
Great Horton Road
Bradford BD7 1DP
UK

Room G23, Richmond tel. (44) (1274) 235957
msg281002 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2016-11-16 22:30
> Is this behaviour documented? Or are you just expected to know what C does?

Indeed, it's not as well documented as it should be. I think that's partly for historical reasons: before Python 2.7, Python's % formatting more-or-less delegated directly to the underlying C sprintf library function, and so just inherited whatever the behaviour of that function happened to be on the target operating system. Because the C standard doesn't make guarantees about the behaviour of %f for ties, Python wasn't in a position to do so either.

But that excuse doesn't work any more with Python 2.7 and Python 3.x, where on most (but still not all) platforms, we're consistently rounding results using the usual round-ties-to-even rounding mode.

There's a currently open issue (#17259) to improve the documentation here.
msg281011 - (view) Author: William McIlhagga (William McIlhagga) Date: 2016-11-16 23:23
Thanks, maybe I should get off my ass and contribute to the documentation
then ...

On 16 November 2016 at 22:30, Mark Dickinson <report@bugs.python.org> wrote:

>
> Mark Dickinson added the comment:
>
> > Is this behaviour documented? Or are you just expected to know what C
> does?
>
> Indeed, it's not as well documented as it should be. I think that's partly
> for historical reasons: before Python 2.7, Python's % formatting
> more-or-less delegated directly to the underlying C sprintf library
> function, and so just inherited whatever the behaviour of that function
> happened to be on the target operating system. Because the C standard
> doesn't make guarantees about the behaviour of %f for ties, Python wasn't
> in a position to do so either.
>
> But that excuse doesn't work any more with Python 2.7 and Python 3.x,
> where on most (but still not all) platforms, we're consistently rounding
> results using the usual round-ties-to-even rounding mode.
>
> There's a currently open issue (#17259) to improve the documentation here.
>
> ----------
>
> _______________________________________
> Python tracker <report@bugs.python.org>
> <http://bugs.python.org/issue28717>
> _______________________________________
>

-- 
Dr. William McIlhagga
Bradford School of Optometry & Vision Science,
Bradford University
Great Horton Road
Bradford BD7 1DP
UK

Room G23, Richmond tel. (44) (1274) 235957
History
Date User Action Args
2022-04-11 14:58:39adminsetgithub: 72903
2016-11-16 23:23:39William McIlhaggasetmessages: + msg281011
2016-11-16 22:30:32mark.dickinsonsetmessages: + msg281002
2016-11-16 21:53:01William McIlhaggasetmessages: + msg280996
2016-11-16 21:37:10mark.dickinsonsetstatus: open -> closed

nosy: + mark.dickinson
messages: + msg280994

resolution: not a bug
stage: resolved
2016-11-16 20:10:59William McIlhaggacreate