[Python-ideas] Fix some special cases in Fractions?

Oscar Benjamin oscar.j.benjamin at gmail.com
Fri Aug 31 10:00:13 EDT 2018


On Thu, 30 Aug 2018 at 17:36, Stephan Houben <stephanh42 at gmail.com> wrote:
>
> I would also like to point out that the current behavior of Fraction
> is consistent with other parts of the numeric system, e.g.
> 1/1 produces 1.0 (rather than 1)
> math.sqrt(4) produces 2.0 (rather than 2)
> 1j-1j produces 0j (rather than 0.0 or 0)
>
> So in general the type of the output is determined by what
> the operation would in general return for that input type,
> as opposed to a more specific type which only applies
> to the specific input value.

An exception is integer exponentiation:

>>> 1 ** 1
1
>>> 1 ** -1
1.0

Given two rationals q1 and q2 usually q1 ** q2 will not be a rational
number. Integer exponentiation results in an integer for half of all
possible integer pairs.

To do the same with Fraction(a, b) ** Fraction(c, d) would require
verifying that both a and b have exact integer dth roots which is more
complicated than simply checking the sign of an integer exponent. The
extra complexity would slow things down a bit but then again the
fractions module is there for precisely those people who are happy to
have substantial slow-down for the sake of exactness.

>From a backwards compatibility perspective the old behaviour would
still be available in a way that works already: float(q1) **
float(q2).

Also it would also be straight-forward to implement this given the
integer maths (iroot etc) functions that were discussed in a recent
thread on this list:
https://mail.python.org/pipermail/python-ideas/2018-July/051917.html

However: Why would you do this operation if you wanted an exact
result? I have at some point wanted (for ints or Fractions) a function
root(q, n) that gives an exact root or an error. This proposal would
mean that q1 ** q2 would be exact occasionally and would return a
float the rest of the time though. If you care about
exactness/accuracy in the code you write then it is not okay to be
unsure whether your variable is float or Fraction. You need to know
because it makes a big difference to how you calculate things (it
isn't generally possible to write optimal polymorphic code over
exact/inexact arithmetic).

The proposed behaviour would look nicer in an interactive session but
might not be any more useful in situations where you *really* care
about exactness.

--
Oscar


More information about the Python-ideas mailing list