I can't understand the exponents in python

I was working on a simple project and I got a lot of things that made me puzzled
Regarding this code:

def factorial(value): print(value) sign = value ** 0 print(sign) result = 1 for i in range(abs(value), 1, -1): result *= i return result * sign print(pow(-5, 0)) print(-5 ** 0) print(factorial(-5))

I can’t understand why the pow function returned a positive number (1) when I raised a negative number to 0, while -5 ** 0 returns -1, which is a negative number either.
The second thing that I don’t understand is why sign = value ** 0 always return a positive number, not a negative one, for example, If I passed -5 to the function “factorial” the sign variable value would be 1, not -1 while when I printed -5**0 It printed -1, not 1.
Thanks.

So, some of this is maths. The correct answer for any number raised to the power of zero, is one, by definition.

So, pow(-5, 0) is returning the correct result, as expected, by that operation.

-5**0 seems to be interpreted as “the negative value of 5**0”, so it seems like it is evaluating 5**0 and then making that negative.

It seems like saving -5 to a variable and then performing the exponent makes it clear that you are taking an exponent of the entire thing, and it is then correctly returning 1, as the zeroth exponent of any number.

As far as factorials go, they aren’t defined for negative numbers, so anything that checks an exponent should first check that the number is positive, or throw an error.

3 Likes

Hey Alex,
Thanks for the answer, I am trying to make the factorial function works as google calculator does for example, if you type -5! in the google search it will return to you -120.
I still don’t understand why variable powered to 0 gives a different result than direct number powered to zero does, may I have references about this?
Thank you.

1 Like

Hi,
-5 ** 0 is being worked out as -(5 **0)
not (-5) ** 0 - which is what is happening in the variable part.
It’s the way Python is trying to sort out the order of operations.

2 Likes

This one seems to cover plenty (also does logarithms which is a nice addition). The bit about 0 comes in halfway through but I think the whole thing it worth a read-
https://www.mathsisfun.com/algebra/exponents-logarithms.html

As @pluginmaybe mentions, the exponent ** has a higher precedence in Python than the unary negation -: https://docs.python.org/3/reference/expressions.html#operator-precedence

That’s probably the same for the google answer (the factorial ! operates before the negation), you could try forcing precedence with parentheses or wolfram alpha is an excellent resource for mathematics-

1 Like

Hey, Mark thanks for the answer,
I’m still curious why it threw the negative sign outside the parenthesis and how it didn’t know there is a negative sign in the variable??
Sorry for my curiosity :blush:.

Hi, nowt wrong with being curious.
I’m not totally sure what’s happening under the hood, but my assumption is;
for - 5 ** 0, python works through it’s order of operations, sees the exponent, does that, and then evaluates the minus sign.
whereas for
value = -5
value ** 0
it knows that value is meant to be treated as one entity, so effectively uses it as (-5), and we’ll get the result we expect.

I think the main thing is to remember to test things, as things wont always work the way you assume they will…