The obvious way to compute is to add your way up from the bottom, which costs . There is a better way, and it comes from noticing that Fibonacci is secretly a matrix power.
Where the matrix comes from
The Fibonacci numbers appear as the successive convergents of the continued fraction for the golden ratio :
The matrix formed from successive convergents of any continued fraction has determinant , and for this one that matrix is . Raising it to the power lays out three consecutive Fibonacci numbers:
So computing reduces to computing a matrix power, and the answer falls out of position .
That alone buys nothing. Multiplying the matrix by itself one step at a time is multiplications — the same as just adding, with more bookkeeping.
Fast exponentiation
The saving comes from how you take the power. To compute , compute once and square it, throwing in one extra multiplication when is odd:
Each step halves , so there are multiplications instead of . Since each matrix multiply is a fixed 8 multiplications and 4 additions, the whole thing is .
| Approach | Time | Space |
|---|---|---|
| Naive recursion | ||
| Iterative addition | ||
| Matrix, step by step | ||
| Matrix, fast power |
Implementation
#include <stdio.h>
void multiply(int F[2][2], int M[2][2]);
void power(int F[2][2], int n);
int fib(int n) {
int F[2][2] = {{1, 1}, {1, 0}};
if (n == 0)
return 0;
power(F, n - 1);
return F[0][0];
}
void power(int F[2][2], int n) {
if (n == 0 || n == 1)
return;
int M[2][2] = {{1, 1}, {1, 0}};
power(F, n / 2);
multiply(F, F);
if (n % 2 != 0)
multiply(F, M);
}
void multiply(int F[2][2], int M[2][2]) {
int x = F[0][0] * M[0][0] + F[0][1] * M[1][0];
int y = F[0][0] * M[0][1] + F[0][1] * M[1][1];
int z = F[1][0] * M[0][0] + F[1][1] * M[1][0];
int w = F[1][0] * M[0][1] + F[1][1] * M[1][1];
F[0][0] = x;
F[0][1] = y;
F[1][0] = z;
F[1][1] = w;
}
int main() {
printf("%d\n", fib(15));
return 0;
}610The four highlighted lines are the entire optimisation. power(F, n / 2) recurses on half the exponent, multiply(F, F) squares the result, and the odd case folds in one more copy of the base matrix.
Two details are easy to get wrong. fib calls power(F, n - 1) rather than power(F, n), because F already starts as rather than the identity. And multiply writes into four temporaries before assigning, since overwriting F[0][0] early would corrupt the values the later expressions still need to read.
WARNING
This returns int, which is 32 bits on most platforms. is the last value that fits — fib(47) silently overflows and comes back negative. If you need to go further, switch to unsigned long long (good to ) or reach for a big-integer library. The algorithm stays in multiplications either way, though the multiplications themselves stop being constant-time once the numbers outgrow a machine word.