[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