[Python-ideas] Fix some special cases in Fractions?
Brendan Barnwell
brenbarn at brenbarn.net
Thu Aug 30 03:38:04 EDT 2018
On 2018-08-30 00:07, Greg Ewing wrote:> Jonathan Goble wrote:
>> How? Raising something to the 2/3 power means squaring it and then
>> taking the cube root of it.
>
> On reflection, "wrong" is not quite accurate. A better
> word might be "surprising".
>
> (-1) ** (2/3) == 1 would imply that 1 ** (3/2) == -1.
> I suppose that could be considered true if you take the
> negative solution of the square root, but it seems a
> bit strange, and it's not what Python gives you for
> the result of 1 ** (3/2).
>
> If you want a solution that round-trips, you need
> complex numbers. That's what Python does when you use
> floats. Making Fractions do something different would
> make it inconsistent with floats.
>
> My calculator (which only does real floats) reports an
> error when trying to evaluate (-1) ** (2/3).
The problem is that in the minds of most people who know enough math to
know about fractional exponents, but still don't enough to want to deal
with complex numbers, the standard procedure when taking a fractional
power of a real number is:
1) choose a positive real value if there is one
2) choose a negative real value otherwise
3) give up if the answer would be nonreal
But if you're willing to go to complex numbers, then the logic shifts
to "take the principal root", which is the root in the complex plane
that you get to first when going in the mathematically positive
direction (counterclockwise) from the positive real axis.
In addition, I think having 2 in the numerator in the fractional power
is a red herring as far as understanding the confusion. This is already
going to be surprising to people:
>>> (-1) ** (1/3)
(0.5000000000000001+0.8660254037844386j)
In high school math, people are taught that (-1)^(1/3) = -1, because
that's the only real value. But if you open up to the complex numbers,
then you'll start defining (-1)^(1/3) as (-1 + sqrt(3)i)/2 since that is
the more mathematically defensible principal value. (Interestingly,
Wolfram Alpha by default gives -1 for "cube root of -1", but gives the
complex value for "(-1)^(1/3)". If only we had a way to type an
nth-root symbol instead of having to indicate roots with exponents!)
Personally I think I was happier with the way things worked in Python
2, where (-1)**(1/3) would raise an error, and you had to explicitly do
(-1 + 0j)**(1/3) if you wanted a complex root. I'm willing to bet that
the vast majority of users doing arithmetic with Python never want nor
can make any use of a complex value for any operation, ever; it is more
likely they want an error message to alert them that their data has gone
awry.
--
Brendan Barnwell
"Do not follow where the path may lead. Go, instead, where there is no
path, and leave a trail."
--author unknown
More information about the Python-ideas
mailing list