[Uncle Timmy]
> I doubt `fsum()` would add much value here: all the addends have the
> same sign, so cancellation is impossible
fsum() may be overkill for this problem. I mentioned it because the math module already had the requisite code and because it improved accuracy with high dimensional data in machine learning examples I've encountered:
>>> from math import fsum, sqrt
>>> n = 1000
>>> sum([0.1] * n)
99.9999999999986
>>> fsum([0.1] * n)
100.0
>>> sqrt(sum([0.1] * n) / n)
0.3162277660168357
>>> sqrt(fsum([0.1] * n) / n)
0.31622776601683794
# fsum() version exactly matches the decimal crosscheck
>>> getcontext().prec = 40
>>> (sum([Decimal(0.1)] * n) / n).sqrt()
Decimal('0.3162277660168379419769730258850242641698')
If we care about those little differences (about 80 ulp in this example), the single-rounding dot products seems like a better way to go. |