Quite a while ago, I presented a fast exponentiation algorithm that uses the binary decomposition of the exponent to perform products to compute .

While discussing this algorithm in class, a student asked a very interesting question: what’s special about base 2? Couldn’t we use another base? Well, yes, yes we can.

Indeed, there’s nothing special about base 2, except maybe that it’s very simple, and it yields a very simple implementation. For example:

unsigned expo_iter(unsigned x, unsigned p) { unsigned t=x, e=1; while (p) { if (p&1) e*=t; t*=t; p/=2; } return e; }

This simple procedures raises to the th power in steps. And they’re (mostly) inexpensive: a shift right by one bit, a mask, and a multiply (which could be expensive if the objects are complex and we can’t rely on machine-sized multiplications).

But what about other bases? Say, base 7? or 3? or whatever other than 1?

First, we must understand what the binary algorithm does. It exploits the fact that in a very specific way: the exponent will be broken into powers of two, so that becomes ; and indeed the powers to use are given by the binary representation of 25, 11001 (which is !). Now, let us see that the above algorithm does. The following table gives you what the algorithm computes at step :

Step | e | p | t |

(init) | 25 | ||

1 | 25 | ||

2 | 12 | ||

3 | 6 | ||

4 | 3 | ||

5 | 1 | ||

(done) | 0 | — |

So it is clear that the number of iterations is given by the position of the most significant bit in the exponent (assuming it’s integer!), and we do at most two multiply (and one shift) per round.

*

* *

So how do we generalize this algorithm from base 2 to some base ? Certainly, the decomposition of the exponent in base is necessary. Let’s pick (because it’s not 2 and it’s also not too big) and (also, no special reason other than a good mix of digits and just long enough we can figure something out of them). We will use the digits to multiply each group of powers of 3 so that the total is 98. Indeed, we have . Indeed:

0

Step | e | m | p | t |

(init) | — | 1 | x | |

1 | 2 | |||

2 | 2 | |||

3 | 1 | |||

4 | 0 | |||

5 | 1 | |||

(done) | — |

Now, let’s turn that into code! Here, *Mathematica* will help us deal with arbitrary large numbers.

expo[x_, e_, b_: 2] := Module[{tx = x, p = 1, te = e, m}, While[te != 0, m = Mod[te, b]; If[m != 0, p *= tx^m]; te = Quotient[te, b]; If[te != 0, tx = tx^b]; (* if product is expensive *) ]; p ]

*

* *

This algorithm trades-off the number of iterations (from to to raise to the th power) for a more complex inner loop: div/mod by something else than 2 could be expensive—even if divmod is likely just one instruction!

Your “a while ago” link at the start seems to be empty?

I’ll fix that right away