Skip to content

Fast powers

Since x to the n is the square of x to the n/2, a power needs about log₂ n squarings instead of n − 1 multiplications, and the bits of n say where to multiply by x.

Helps to know first
This topic

First, the picture

How would you work out 313? The obvious way is to start with 3 and multiply by 3 twelve more times. But there is a shortcut. 313 is 3 × 312, and 312 is the square of 36, and 36 is the square of 33. Each step halves the exponent. Watch how few multiplications that leaves.

Raising to a power in few steps

3¹³ by halving the exponent

#include <stdio.h> static int mults = 0; long long power(long long x, int n){    if (n == 0)        return 1;    long long half = power(x, n / 2);    long long result = half * half;    mults++;    if (n % 2 == 1) {        result = result * x;        mults++;    }    return result;} long long power_loop(long long x, int n){    long long result = x;    for (int i = 1; i < n; i++) {        result = result * x;        mults++;    }    return result;} int main(void){    long long a = power(3, 13);    printf("power: %lld in %d multiplications\n", a, mults);    mults = 0;    long long b = power_loop(3, 13);    printf("loop: %lld in %d multiplications\n", b, mults);    return 0;}

main calls power(3, 13).

multiplications by power
0
by the loop
0

Output

0.00 / 23.05 s
Describe this picture

The 37 lines of power.c with the line about to run marked, beside a picture in two parts. At the top, under the label “Call stack”, is one card per call that has not returned yet: main’s with its a and b, then cards named power(3, 13), power(3, 6) and so on, each with two boxes, half and result, a ”?” until written. The running call’s card is edged in the accent colour; a returning card shows the value it hands back in a badge, and that value flies into the half box of the card above. Below the stack is a row of four bit cells, labelled under the row “13 in binary: each call’s n % 2”. Each cell holds 1 or 0, and the label over it names the call it belongs to: n=1, n=3, n=6 and n=13, from left to right, which reads 1 1 0 1. Cells of calls that have not tested their n yet are greyed; a cell whose call is testing its n is outlined. The clip plays the program once, about 23 seconds, and rests on the end. First, five cards pile up as 13 halves to 6, 3, 1 and 0. power(3, 0) returns 1. Then, on the way back, each card squares its half and, when its n is odd, multiplies by 3 once more, and its bit lights in the row from the left: power(3, 1) returns 3, power(3, 3) returns 27, power(3, 6) returns 729 and power(3, 13) returns 1594323. Then power_loop(3, 13) runs quickly in one card, its result multiplied by 3 twelve times while i counts from 1 to 12. Under the picture are one sentence on the current step, two readouts, “multiplications by power” (it ends at 7) and “by the loop” (it ends at 12), and the output: power: 1594323 in 7 multiplications and loop: 1594323 in 12 multiplications. The transport plays and pauses, steps back or forward, and scrubs; a paused step is kept in the page address as fast-power.step.

Halving the exponent

Here is the rule the program uses. When n is even, xn is xn/2 times itself. When n is odd, take one x out first:

xn=(xn/2)2 for even n,xn=x⋅(x⌊n/2⌋)2 for odd n,x0=1.x^n = \left(x^{n/2}\right)^2 \text{ for even } n, \qquad x^n = x \cdot \left(x^{\lfloor n/2 \rfloor}\right)^2 \text{ for odd } n, \qquad x^0 = 1.

The brackets ⌊ ⌋ mean “rounded down”, which is what n / 2 does in C when n is an int: 13 / 2 is 6. So it works for every n, not only powers of 2. In C:

long long power(long long x, int n)
{
    if (n == 0)
        return 1;
    long long half = power(x, n / 2);
    long long result = half * half;
    mults++;
    if (n % 2 == 1) {
        result = result * x;
        mults++;
    }
    return result;
}

In the clip, 13 halves to 6, then 3, then 1, then 0, and the base case returns 1. Then the cards return, the deepest first:

Callhalfsquaredn odd?returnsmultiplications so far
power(3, 1)11 × 1 = 1yes: × 332
power(3, 3)33 × 3 = 9yes: × 3274
power(3, 6)2727 × 27 = 729no7295
power(3, 13)729729 × 729 = 531,441yes: × 31,594,3237

Seven multiplications, against the loop’s twelve.

Key idea

To raise x to the power n, raise it to the power n/2 (rounded down) and square the answer; if n is odd, multiply by x once more. The exponent halves at every call.

The code and its cost

The bits of n

Look at the row of bits in the clip. Each call’s n is the one above it halved, so each call’s n % 2, odd or even, is one bit of 13 written in binary. Read from the deepest call to the first, the bits are 1, 1, 0, 1, and 1101 in binary is 8 + 4 + 0 + 1 = 13.

That gives the count. Every call with n above 0 makes one squaring, and there is one call for each bit of n. Every 1 bit adds one multiplication by x. So:

multiplications=(number of bits of n)+(number of 1 bits of n).\text{multiplications} = (\text{number of bits of } n) + (\text{number of 1 bits of } n).

For 13, that is 4 + 3 = 7. The number of bits of n is ⌊log₂ n⌋ + 1, so the count is at most about 2 log₂ n. The loop always needs n − 1. In the notation of Time and space complexity (3.3), the halving version takes O(log n) time and the loop O(n). The stack holds one frame per bit, O(log n) as well.

The work here is the multiplications: everything else a call does is a test, a halving and a return. So fewer multiplications really is less work.

The loop that reads the bits

The same idea works without recursion. Go through the bits of n from the right. Keep x squared as you go, so at each bit x holds 3, 9, 81, 6561: the powers 31, 32, 34, 38. Whenever the bit is 1, multiply the result by the current x:

long long power_bits(long long x, int n)
{
    long long result = 1;
    while (n > 0) {
        if (n % 2 == 1)
            result = result * x;
        x = x * x;
        n = n / 2;
    }
    return result;
}

This uses one frame. It reads the same bits as the recursion, in the opposite order.

The plain loop

power_loop in the program is the obvious method: start with x and multiply by x, n − 1 times. It only works for n of 1 or more; for n = 0 it would return x instead of 1.

Running it yourself

gcc -std=c11 -Wall -Wextra -pedantic power.c -o power
./power

It prints power: 1594323 in 7 multiplications, then loop: 1594323 in 12 multiplications.

Worked example

The bit loop for 313, by hand. Each row is the state at the top of the while loop:

nits last bitresultx
13113
6039
31381
112436,561
0(stop)1,594,32343,046,721

At n = 13 the bit is 1, so result becomes 1 × 3 = 3. At n = 6 it is 0, and only x changes. At n = 3, result becomes 3 × 81 = 243. At n = 1, result becomes 243 × 6,561 = 1,594,323.

A million. In binary, 1,000,000 is 11110100001001000000: 20 bits, 7 of them 1. So power makes 20 + 7 = 27 multiplications, where the loop would make 999,999. A program that counts them, power-mod.c, agrees: 27.

Overflow. 31,000,000 has far too many digits for any C integer. The largest long long here is 9,223,372,036,854,775,807. 339 = 4,052,555,153,018,976,267 fits; 340 = 12,157,665,459,056,928,801 does not, and multiplying past it is undefined in C.

Remainders. To get past that, many programs keep only the remainder after dividing by some number m, at every step. The remainder of a product depends only on the remainders of the factors, so the answer comes out right. With m = 7, power-mod.c gets 313 mod 7 = 3. Check: 1,594,323 = 7 × 227,760 + 3. It also gets 31,000,000 mod 1,000,000,007 = 64,935,414, in those 27 multiplications.

Where it’s used

Public-key cryptography. Encryption methods such as RSA raise a number to a power with hundreds of digits, keeping remainders at every step. The loop would never finish. Halving needs a few thousand multiplications at most.

Powers of a matrix. The same rule squares matrices instead of numbers. In linear algebra, Diagonalisation gives another way to raise a matrix to a power. A 2 × 2 matrix raised to the power n by halving gives fib(n) in O(log n) multiplications, against the exponential calls of Tree recursion (4.3).

Maths libraries. Functions that raise a number to a whole-number power use this method, because it needs so few multiplications.

Reference card

IdeaIn this lesson
halving rulexn = (xn/2)2 for even n; x · (x⌊n/2⌋)2 for odd n; x0 = 1
callsone per bit of n, plus the base case: 13, 6, 3, 1, 0
multiplicationsbits of n + 1 bits of n; 313: 4 + 3 = 7
costO(log n) time and stack; the loop O(n) time
the bitseach call’s n % 2 is one bit of n: 13 = 1101
loop formif n is odd multiply result by x; square x; halve n
limitsa long long holds 339 but not 340
remainderskeep the remainder at each step: 313 mod 7 = 3

Platform: C11, gcc on x86-64 Linux: int 4 bytes, long long 8. The cards in the picture show names and values only.

End of the lesson

Where to go next.

New lessons by email

Are you 13 or over?

Accounts and email updates are for people aged 13 or over. We keep only your answer, never your date of birth.

Phasorium

Account

Sign inWith Google, GitHub or your email

Subjects

Site

Look