Mark, thanks! I'm happy with that resolution: if any argument is infinite, return +inf; else if any argument is a NaN, return a NaN; else do something useful ;-)
Serhiy, yes, the scaling that prevents catastrophic overflow/underflow due to naively squaring unscaled values can introduce small errors of its own. A single-rounding dot product could avoid that, leaving two sources of single-rounding errors (the dot product, and the square root).
Raymond, yes, fsum() on its own can reduce errors. Note that scaling on its own can also reduce errors (in particular, when the arguments are all the same, they're each scaled to exactly 1.0):
>>> import math
>>> n = 1000
>>> math.sqrt(sum([0.1 ** 2] * n))
3.1622776601683524
>>> math.sqrt(math.fsum([0.1 ** 2] * n))
3.1622776601683795
>>> hypot(*([0.1] * n)) # using the code above
3.1622776601683795
>>> math.sqrt(n) * 0.1
3.1622776601683795 |