Author tim.peters
Recipients mark.dickinson, rhettinger, serhiy.storchaka, skrah, steven.daprano, tim.peters
Date 2018-03-20.01:49:36
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1521510578.75.0.467229070634.issue33089@psf.upfronthosting.co.za>
In-reply-to
Content
Mark, how about writing a clever single-rounding dot product that merely _detects_ when it encounters troublesome cases?  If so, it can fall back to a (presumably) much slower method.  For example, like this for the latter:

    def srdp(xs, ys):
        "Single rounding dot product."
        import decimal
        from decimal import Decimal, Inexact
        # XXX check that len(xs) == len(ys)
        with decimal.localcontext(decimal.ExtendedContext) as ctx:
            ctx.traps[Inexact] = True
            total = Decimal(0)
            for x, y in zip(map(Decimal, xs), map(Decimal, ys)):
                while True:
                    try:
                        total += x * y
                        break
                    except Inexact:
                        ctx.prec += 1
            return float(total)

So it just converts everything to Decimal; relies on decimal following all the IEEE rules for special cases; retries the arithmetic boosting precision until decimal gets an exact result (which it eventually will since we're only doing + and *); and relies on float() to get everything about final rounding, overflow, and denorms right.  If that doesn't work, I'd say it's a bug in the decimal module ;-)

I'd bet a dollar that, in real life, falling back to this would almost never happen, outside of test cases.
History
Date User Action Args
2018-03-20 01:49:38tim.peterssetrecipients: + tim.peters, rhettinger, mark.dickinson, steven.daprano, skrah, serhiy.storchaka
2018-03-20 01:49:38tim.peterssetmessageid: <1521510578.75.0.467229070634.issue33089@psf.upfronthosting.co.za>
2018-03-20 01:49:38tim.peterslinkissue33089 messages
2018-03-20 01:49:36tim.peterscreate