On Fri, Apr 4, 2014 at 4:08 AM, Steven D'Aprano <steve+comp.lang.pyt...@pearwood.info> wrote: > On Fri, 04 Apr 2014 02:13:13 -0600, Ian Kelly wrote: > >> On Fri, Apr 4, 2014 at 1:52 AM, Steven D'Aprano >> <steve+comp.lang.pyt...@pearwood.info> wrote: >>> py> from decimal import * >>> py> getcontext().prec = 16 >>> py> x = Decimal("0.7777777777787516") py> y = >>> Decimal("0.7777777777787518") py> (x + y) / 2 >>> Decimal('0.7777777777787515') >>> >>> "Guido, why can't Python do maths???" >> >> Well, you need to work within the system: >> >>>>> (5*x + 5*y) / 10 >> Decimal('0.7777777777787517') >> >> Actually, I have no idea whether that formula can be relied upon or the >> correctness of the above was just luck. > > > And what happens when x+y would have been calculated correctly, but one, > or both, of 5*x or 5*y loses catastrophically loses accuracy due to > overflow? > > py> x = 3.1e307 > py> y = 3.3e307 > py> (x+y)/2 > 3.2e+307 > py> (5*x+5*y)/10 > inf > > (I've used regular floats here out of laziness, the same principle > applies to Decimals -- there will be *some* number x which is finite, but > 5*x overflows to infinity.)
I thought that Decimals had arbitrary-precision exponents, at least in the pure Python version. Turns out that's wrong; although the context.Emax can be set to any int in the pure Python version, it can't be removed entirely. One could just temporarily upgrade the Emax for the above calculation, but the pure Python version was made inconvenient to use voluntarily in CPython 3.3, and the C version has strict limits. In any event, the exponent limits for decimals are much higher than for floats (the default Emax is 999999, and it can be set roughly within the limits of C integer precision), so any case where you'll get overflow with a Decimal is already far beyond the point where you'd have gotten overflow with a float. -- https://mail.python.org/mailman/listinfo/python-list