2

I'm trying to write a small program that calculate exponents recursively and I am a bit stuck. It is a homework assignment and we have been asked to have a base case, when the exponent is an odd number and when the exponent is even. So far I have this:

def quick_power(x,n):
    if n == 0:
        return 1
    elif n % 2 != 0:
        return x * quick_power(x, n-1)
    elif n % 2 == 0:
        return quick_power(quick_power(x, n//2), 2)

And I know that the line with n % 2 == 0 isn't what it should be. Any help is appreciated. Thanks.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Mikey
  • 149
  • 3
  • 13
  • why do you have those even/odd checks? – Anand S Kumar Aug 16 '15 at 01:46
  • @Anand: The question says that the assignment said that there should be those checks. That said, there is a good reason: this is the algorithm for [exponentiation by squaring](https://en.wikipedia.org/wiki/Exponentiation_by_squaring). – icktoofay Aug 16 '15 at 01:48

3 Answers3

4

Let’s say we’re evaluating quick_power(1234, 2). The evaluation goes like this:

  1. quick_power(1234, 2)
  2. quick_power(quick_power(1234, 1), 2)
  3. quick_power(1234 * quick_power(1234, 0), 2)
  4. quick_power(1234 * 1, 2)
  5. quick_power(1234, 2)

…as you can see, it eventually starts evaluating back where we started, so you end up with infinite recursion. Without giving you the solution, I advise you to think: if we have a constant exponent (here, 2), is there a way you can compute that without having to do it recursively?

icktoofay
  • 126,289
  • 21
  • 250
  • 231
  • I think I have found the solution. I will post below – Mikey Aug 16 '15 at 01:50
  • Is there any chance I could quickly jump into a chat with you and ask you a few question please? This recursion thing is really hurting my head! – Mikey Aug 16 '15 at 01:55
  • @Mikey: Sure. I’m not entirely sure how Stack Overflow Chat is supposed to work, but here’s a link and maybe it works: https://chat.stackoverflow.com/rooms/87074/discussion-on-question-32031093 – icktoofay Aug 16 '15 at 02:04
0
def quick_power(x,n)

if n == 0:
    return 1
elif n % 2 == 0:
    return quick_power(x * x, n / 2)
else:
    return x * quick_power(x * x, (n - 1) / 2)
Mikey
  • 149
  • 3
  • 13
0

Expanding on what's above:

A recursive algorithm has recursion cases ans base cases (where a definite result is returned instead of another recursion), as you probably know...

For this situation, you covered the base cases n=0 and n=1. But from @icktoofay's response there is another base case, n=2.

So your code could be written:

def quick_power(x,n):
    if n == 0:
        return 1
    elif n == 1:
        return x
    elif n == 2:
        return x * x
    elif n % 2 != 0:
        return x * quick_power(x, n-1)
    elif n % 2 == 0:
        return quick_power(x,n//2) * quick_power(x,n//2)

The last line is supposed to be more efficient by reducing the maximum depth of recursion ( to log2(n) recursions ), by the way.

rask004
  • 552
  • 5
  • 15
  • In the last line, you really ought to be calculating the recursive thing *once* and then squaring that; otherwise, you’re doing the recursion twice, which throws out all the performance benefits of square-and-multiply and reduces to iterated multiplication. – icktoofay Aug 20 '15 at 03:10
  • You're right actually, that reduces the number of calls while keeping to the same recursion level. – rask004 Aug 23 '15 at 20:03