DSA Fast Power and Modular Arithmetic
Fast power is a method that raises a base to a large exponent by repeated squaring. A modular remainder keeps every intermediate value below a fixed bound.
Squaring beats step by step
A plain loop for 3 to the 13th power multiplies 12 times. Squaring follows the binary digits of 13 instead.
steps = 0
result = 3
for _ in range(12):
result *= 3
steps += 1
print("plain loop answer:", result, "multiplications:", steps)
print("13 in binary:", format(13, "b"))Remainders keep values small
Without a modulus the power grows to 17 digits in this small case. With a remainder after each step the value stays below the modulus.
big = 7 ** 20
print("7 to the 20th:", big)
print("digits:", len(str(big)))
value = 1
for _ in range(20):
value = (value * 7) % 5
print("7 to the 20th mod 5:", value)
print("built-in check:", pow(7, 20, 5))Read the exponent in binary
The exponent 10 is 1010 in binary, so two squared values multiply in. The squares are 2, 4, 16 and 256.
squares = []
value = 2
for _ in range(4):
squares.append(value)
value = value * value
print("squares of 2:", squares)
print("2 to the 10th from squares:", squares[1] * squares[3])Example
def fast_power_mod(base, exp, mod):
steps = 0
result = 1 % mod
while exp > 0:
if exp & 1:
result = (result * base) % mod
steps += 1
base = (base * base) % mod
steps += 1
exp = exp >> 1
return result, steps
cases = [(2, 100, 1000), (3, 50, 97), (123, 45, 100000), (7, 1000, 13)]
for base, exp, mod in cases:
value, steps = fast_power_mod(base, exp, mod)
print(base, "to the", exp, "mod", mod, "=", value, "| multiplications:", steps, "| matches built-in:", value == pow(base, exp, mod))Key points
- Fast power raises a base to an exponent by repeated squaring.
- Squaring means multiplying a value by itself.
- The binary form of the exponent selects which squared values get multiplied in.
- A modular remainder is the remainder of a value after division by the modulus.
- Taking the remainder after each multiplication keeps the answer unchanged.
- The remainder rule holds because extra full turns of the modulus add nothing.
- Each halving of the exponent adds at most two multiplications.
In this example, each case runs the squaring loop with a counter. The counter rises once per multiplication the loop performs. The binary length of the exponent caps how many steps can run. A plain loop would need one multiplication per exponent step. The last column checks every answer against the built-in modular power.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Python Playground
Exercise
How many squarings can an exponent below 64 need at most?