New submission from Arne Babenhauserheide <arne_...@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 <rep...@bugs.python.org> <http://bugs.python.org/issue13060> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com