On Fri, 15 Jul 2016 09:48 pm, Chris Angelico wrote: >> py> product_scaled([2.5, 3.5]) # expected 8.75 >> 2.734375 >> > > You're chaining your product twice. (Also your scale, although that > appears to be correct.) Changing it to "prod = m1 * m2" gives 8.75.
D'oh! Thanks! I needed some fresh eyes on that, because I have been staring at it for two days. > But what do you gain by this? You're still stuffing the result back > into a float at the end, so all you do is change from getting > float("inf") to getting OverflowError. How can you make it not > overflow? If the result is too big to be represented as a float at the end of the product, then of course it will overflow. But this can give some protection against overflow of intermediate values. Consider multiplying: 2.0, 1e200, 1e200, 1e-200, 1e-200, 3.0 Mathematically, the answer should be 6. In principle, by rescaling when needed to prevent overflow (or underflow), product() should be able to get something very close to 6, if not exactly 6. But I'm not actually writing a general product() function. I'm doing this for geometric mean, so I return the scaling exponent and the mantissa[1] separately, and then take the nth-root of them individually, before combining them into the final result. Here's an example from my test suite. I can take the geometric mean of: [2.0**900, 2.0**920, 2.0**960, 2.0**980, 2.0**990] and get to within a relative error of 1e-14 of the correct answer, 2**950: py> geometric_mean([2.0**900, 2.0**920, 2.0**960, 2.0**980, 2.0**990]) 9.516908214257811e+285 py> 2.0**950 9.516908214257812e+285 Here's one that's exact: py> geometric_mean([2e300, 4e300, 8e300, 16e300, 32e300]) 8e+300 [1] I don't care what it's actually called :-) -- Steven “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list