[Python-ideas] Fix some special cases in Fractions?
Neil Girdhar
mistersheik at gmail.com
Thu Aug 30 07:31:10 EDT 2018
Thanks for the feedback.
On Thu, Aug 30, 2018 at 7:13 AM Paul Moore <p.f.moore at gmail.com> wrote:
> (You're still not fixing your mail headers. Please do, it's hard to be
> bothered responding if I keep having to fix your mails in order to do
> so).
>
> On Thu, 30 Aug 2018 at 11:28, Neil Girdhar <mistersheik at gmail.com> wrote:
> >
> > But I'm only asking for fractional powers of -1, 0, and 1. Is that
> really a complex issue?
>
> Yes. (Even ignoring the oh-so-tempting complex number joke ;-)). As
> has been seen here there's no agreement on the "right" choice of which
> root of -1 to choose. Or possibly more accurately, no-one else is
> agreeing with your suggestion that we choose a different option for
> the case you're arguing over.
>
> And to be 100% precise, you asked for the results of three *very
> specific* calculations to change. I guess you actually want something
> more general - or are you really OK with (for example)
> Fraction(-1,1)**Fraction(2,3) changing as you request, but
> Fraction(-2,1)**Fraction(2,3) remaining as it currently is?
Powers of other numbers have to keep the same behavior since in general
those kinds of expressions don't create rational numbers.
> You still
> haven't clarified (no-one has particularly asked yet - you may
> consider this a request to do so if you like) how you propose in
> general that the result of
>
> Fraction(-1,1) ** Fraction(a, b)
> and/or
> Fraction(1,1) ** Fraction(a, b)
> or maybe even more generally
> Fraction(c,d) ** Fraction(a,b)
>
> would change. What exactly are the special cases you want to define
> different results for? What is the process for choosing the result?
>
Here's my proposed method:
class Fraction:
def __pow__(a, b):
"""a ** b
If b is not an integer, the result will be a float or complex
since roots are generally irrational. If b is an integer, the
result will be rational.
"""
if isinstance(b, numbers.Rational):
if b.denominator == 1:
power = b.numerator
if power >= 0:
return Fraction(a._numerator ** power,
a._denominator ** power,
_normalize=False)
elif a._numerator >= 0:
return Fraction(a._denominator ** -power,
a._numerator ** -power,
_normalize=False)
else:
return Fraction((-a._denominator) ** -power,
(-a._numerator) ** -power,
_normalize=False)
elif a == -1 and b.denominator % 2 == 1:
return Fraction(-1 if b.numerator % 2 == 1 else 1)
elif a == 0:
if b > 0:
return Fraction(0)
else:
raise ZeroDivisionError(
"0 cannot be raised to a negative power")
elif a == 1:
return Fraction(1)
else:
# A fractional power will generally produce an
# irrational number.
return float(a) ** float(b)
else:
return float(a) ** b
Compare it with
https://github.com/python/cpython/blob/3.7/Lib/fractions.py#L448
>
> > You are right that the fractional power of -1 and 1 has multiple values,
> but the fractional power of zero has a unique value.
>
> And that part of your proposal has not generated much controversy.
> Maybe if you proposed only that, you might get that change made? I
> haven't considered the ramifications of that because the discussions
> about -1 are obscuring it, but it might be relatively uncontroversial.
>
Fair enough.
>
> Paul
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20180830/95a70777/attachment-0001.html>
More information about the Python-ideas
mailing list