2016-07-15 13:39 GMT+02:00 Steven D'Aprano <st...@pearwood.info>: > I'm experimenting with various implementations of product(values). Here's a > naive version that easily suffers from overflow: > > from functools import reduce > from operator import mul > > def product_naive(values): > return reduce(mul, values) >... > -- > Steven > -- > https://mail.python.org/mailman/listinfo/python-list
Hi, just to add another approach to already proposed ones, I thought about using fractions for computations instead of floats where possible. The accuracy shoud be better, - it works fine for my tests with multiplying however, the downside is - for computing fractional power the fractions fall back to float, as irrational numbers are expected in the output, hence the float overflow is also possible (unless an individual implementation of the root computation would be used in gmean...). The hackish code in adapt_float_exp enhances the accuracy compared to directly building Fractions from large floats in exponential notation. (I can realise, that this approach might be insufficient for the scale you intend to support, due to the mentioned fallback to floats.) Regards, vbr ======================== #! Python # -*- coding: utf-8 -*- from fractions import Fraction def adapt_float_exp(flt): """Return Fraction extracted from float literal in exponential notation.""" if "e" not in str(flt).lower(): return Fraction(flt) else: mant_str, exp_str = str(flt).lower().split("e") return Fraction(mant_str) * 10 ** Fraction(exp_str) def prod_fract(*args): prod = 1 for arg in args: if isinstance(arg, float): arg = adapt_float_exp(arg) prod *= arg return prod def gmean(*args): prod = prod_fract(*args) root = Fraction(prod) ** Fraction(1, len(args)) # fractional power ** - irrational - implemented via floats !! - overflow ... return root print(repr(prod_fract(2.0, 1e200, 1e200, 1e-200, 1e-200, 3.0))) print(repr(gmean(2.0, 1e200, 1e200, 1e-200, 1e-200, 3.0))) -- https://mail.python.org/mailman/listinfo/python-list