Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #111529

Re: math.frexp

From Vlastimil Brom <vlastimil.brom@gmail.com>
Newsgroups comp.lang.python
Subject Re: math.frexp
Date 2016-07-17 01:18 +0200
Message-ID <mailman.44.1468711119.2307.python-list@python.org> (permalink)
References <5788cb76$0$1599$c3e8da3$5496439d@news.astraweb.com> <CAHzaPEOQq95aMo5soGTU=+p+DCB7DYL_UKdtnvsBbeLWt_pMeg@mail.gmail.com>

Show all headers | View raw


2016-07-15 13:39 GMT+02:00 Steven D'Aprano <steve@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)))

Back to comp.lang.python | Previous | NextPrevious in thread | Find similar | Unroll thread


Thread

math.frexp Steven D'Aprano <steve@pearwood.info> - 2016-07-15 21:39 +1000
  Re: math.frexp Chris Angelico <rosuav@gmail.com> - 2016-07-15 21:48 +1000
    Re: math.frexp Steven D'Aprano <steve@pearwood.info> - 2016-07-16 02:32 +1000
      Re: math.frexp Chris Angelico <rosuav@gmail.com> - 2016-07-16 02:44 +1000
      Re: math.frexp Random832 <random832@fastmail.com> - 2016-07-15 14:28 -0400
      Re: math.frexp Paul Rubin <no.email@nospam.invalid> - 2016-07-15 13:24 -0700
        Re: math.frexp Steven D'Aprano <steve@pearwood.info> - 2016-07-16 20:21 +1000
          Re: math.frexp Paul Rubin <no.email@nospam.invalid> - 2016-07-16 12:49 -0700
  Re: math.frexp Nobody <nobody@nowhere.invalid> - 2016-07-15 17:39 +0100
  Re: math.frexp Vlastimil Brom <vlastimil.brom@gmail.com> - 2016-07-17 01:18 +0200

csiph-web