[Random832 <random...@fastmail.com>]
> I was making a "convert Fraction to Decimal, exactly if possible" function and
> ran into a wall: it's not possible to do some of the necessary operations with
> exact precision in decimal:
>
> - multiplication
> - division where the result can be represented exactly [the divisor is an
> integer whose prime factors are only two and five, or a rational number
> whose numerator qualifies]

Without you supplying careful concrete examples, I really have no idea
what you're looking for.

> I assume there's some way around it that I haven't spent enough time to figure
> out [create a temporary context with sufficint digits for multiplication, and 
> work
> out the reciprocal power of 10 by hand to use this multiplication to 
> implement division],

Integers have unbounded precision, so stick to those when part of a
computation needs to be unbounded.  If by "Decimal" you mean Python's
"decimal.Decimal" class, the constructor ignores the context
precision, and retains all the info passed to it,  So there's no need
at all to change Decimal precision.

Here's a guess at what you want:

    def frac2dec(f):
        from decimal import Decimal as D
        n, d = f.numerator, f.denominator
        if not n:
            return D(0)
        if d == 1:
            return D(n)
        e2 = e5 = 0
        while d % 2 == 0:
            e2 += 1
            d //= 2
        while d % 5 == 0:
            e5 += 1
            d //= 5
        if d != 1:
            raise ValueError("exact conversion not possible", f)
        n *= (2 if e2 <= e5 else 5) ** abs(e5 - e2)
        return D(f"{n}E-{max(e2, e5)}")

Then, e.g.,

    >>> frac2dec(Fraction(-12311111111111111111111111111111111, 1000))
    Decimal('-12311111111111111111111111111111.111')
    >>> frac2dec(Fraction(-12311111111111111111111111111111111, 500))
    Decimal('-24622222222222222222222222222222.222')
    >>> frac2dec(Fraction(-12311111111111111111111111111111111, 200))
    Decimal('-61555555555555555555555555555555.555')

Or Chris Angelico's example, but it's not really instructive because
Decimal's default precision is enough for exact calculation in this
specific case:

    >>> frac2dec(Fraction(314159265358979323, 2**53 * 5**47))
    Decimal('4.908738521234051921875E-32')

However, you get the same result if you set Decimal's precision to,
e.g., 1 first:

    >>> import decimal
    >>> decimal.getcontext().prec = 1
    >>> frac2dec(Fraction(314159265358979323, 2**53 * 5**47))
    Decimal('4.908738521234051921875E-32')

> but I feel like these exact operations should be supported in the standard
> library.

Since I really don't know what you want, can't say - but _doubt_ any
plausible way of fleshing it out is useful enough to warrant inclusion
in the core.
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/CVD5S3HNUFVEN7MQER6EYYOXTFQ7UV4L/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to