Raise a number to a huge power, modulo m

Complexity analysis Mid-level Python 3.13+ Reviewed By Best Latest Apps

Predict the output

What does this print?

Python 3.13
result, base, exp = 1, 3, 13
mults = 0
while exp:
    if exp & 1:
        result *= base
        mults += 1
    base *= base
    exp >>= 1
print(result == 3 ** 13, mults)

Options

Choose an answer, then open Show answer below to check it.

Show answer

Answer: A True 3

Right: 13 is 1101 in binary, so three bits are set.

The result is multiplied once per set bit, and the loop runs once per bit, so the work is logarithmic in the exponent.

Why not the others?
  • B True 13. Squaring skips most multiplications; only set bits multiply the result.
  • C False 3. The bits of 13 pick 3¹ × 3⁴ × 3⁸, which is 3¹³.
A trace of the variables acc (the running answer), sq (the current square) and exp at each line while computing 2 to the 10 mod 1000 and 3 to the 13 mod 1000.

Traced by running the Python solution.

Text version

2^10 mod 1000 (args [2, 10, 1000]):

Key: acc = the result so far; sq = the current square of the base; exp = the exponent still to use.

Trace: 2^10 mod 1000
Lineaccsqexp
210 (changed)
31 (changed)2 (changed)10
41210
61210
714 (changed)10
3145 (changed)
4145
5145
64 (changed)45
7416 (changed)5
34162 (changed)
44162
64162
74256 (changed)2
342561 (changed)
442561
542561
624 (changed)2561
724536 (changed)1
3245360 (changed)
8245360

21 rows, result 24.

3^13 mod 1000 (args [3, 13, 1000]):

Key: acc = the result so far; sq = the current square of the base; exp = the exponent still to use.

Trace: 3^13 mod 1000
Lineaccsqexp
213 (changed)
31 (changed)3 (changed)13
41313
51313
63 (changed)313
739 (changed)13
3396 (changed)
4396
6396
7381 (changed)6
33813 (changed)
43813
53813
6243 (changed)813
7243561 (changed)3
32435611 (changed)
42435611
52435611
6323 (changed)5611
7323721 (changed)1
33237210 (changed)
83237210

22 rows, result 323.

30-second answer

Repeated squaring: look at the exponent's bits from lowest to highest. Keep a running answer; whenever the current bit is 1, multiply it by the current square. Square that value and shift the exponent right each step. The loop runs once per bit of exp, so it is O(log exp) multiplications with O(1) extra space, and taking mod m each time keeps the numbers small.

Practise saying it · 45 s. No recording, just a timer

Explain exponentiation by squaring.

Say your answer out loud, then check which of these points you covered:

  • Bits of the exponent
  • Square base, shift exp
  • O(log exp)

Deep dive

Multiplying exp times would be O(exp): a billion steps.

The same idea speeds up matrix powers, which gives O(log n) Fibonacci numbers.

Python's pow(base, exp, mod) does this for you; in an interview, write it to show the idea.

Python solution Ran on Python 3.13.5 · mypy --strict
Python 3.13
def power_mod(base: int, exp: int, mod: int) -> int:
    acc, sq = 1 % mod, base % mod
    while exp:
        if exp & 1:  # this bit of the exponent is set
            acc = acc * sq % mod
        sq = sq * sq % mod
        exp >>= 1
    return acc

Common mistakes

  • Forgetting the final % mod when exp is 0 and mod is 1 (the answer must be 0).
  • Computing base ** exp first, which builds an enormous integer.

Senior take & follow-ups

Walk through the bits of a small exponent such as 13 (binary 1101); it makes the loop obvious.

Follow-up questions

Think of your answer first, then open the hint.

  1. How would you compute modular inverses?

    Show hint

    With a prime modulus, base^(m - 2) mod m by Fermat's little theorem.

  2. Can this be done recursively?

    Show hint

    Yes: square the result of exp // 2 and multiply by base if exp is odd; stack depth is O(log exp).

What each operation costs: Bubble Sort · Merge Sort · Binary Search

From the author

DSA Master - Data & Algorithms

Free on iPhone and iPad: watch 50+ data structures and algorithms step through animations, run the code in the playground, and try the daily challenge.

Suggest a fix if something here is wrong or out of date.