[New-bugs-announce] [issue13060] make round() floating-point errors less hurtful
Arne Babenhauserheide
report at bugs.python.org
Thu Sep 29 17:16:50 CEST 2011
New submission from Arne Babenhauserheide <arne_bab at web.de>:
Hi,
I just stumbled over round() errors. I read the FAQ¹, and even though the FAQ states that this is no bug, its implementation is less than ideal.
To illustrate:
>>> round(0.5, 1)
0.0
and
>>> round(5, -1)
0
This is mathematically wrong and hits for comparisions which humans put in.
As alternate I use the following hack myself where ever I have to round numbers:
def roundexact(a, *args):
... return round(a+0.000000000000001*max(1.0, (2*a)//10), *args)
This has correct behavior for *5 on my hardware:
>>> roundexact(0.5, 0)
1.0
Its errors only appear in corner cases:
>>> roundexact(0.4999999999999999, 0)
0.0
>>> roundexact(0.49999999999999998, 0)
1.0
This implementation shields me from implementation details of my hardware in all but very few extreme cases, while the current implementation of round() exhibits the hardware-imposed bugs in cases which actually matter to humans.
Maybe round could get a keyword argument roundup5 or such, which exhibits the behavior that any *5 number is rounded up.
Note: The decimal module is no alternative, because it is more than factor 100 slower than floats (at least for simple computations):
>>> from timeit import timeit
>>> timeit("float(1.0)+float(0.1)")
0.30365920066833496
>>> timeit("Decimal(1.0)+Decimal(0.1)", setup="from decimal import Decimal, getcontext; getcontext().prec=17")
49.96972298622131
¹: http://docs.python.org/library/functions.html?highlight=round#round
----------
components: Interpreter Core
messages: 144590
nosy: ArneBab
priority: normal
severity: normal
status: open
title: make round() floating-point errors less hurtful
versions: Python 3.2
_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue13060>
_______________________________________
More information about the New-bugs-announce
mailing list