Find the nth Fibonacci number Using Fast Doubling Method

Last Updated : 10 Sep, 2026

Given an integer n, the task is to find the n-th Fibonacci numbers.

Examples: 

Input: n = 3 
Output: 2 
Explanation: 
F(1) = 1, F(2) = 1
F(3) = F(1) + F(2) = 2
Hence, the 3rd Fibonacci number is 2.

Input: n = 6
Output: 8
Explanation:
F(1) = 1, F(2) = 1
F(3) = F(1) + F(2) = 2
F(4) = F(2) + F(3) = 3
F(5) = F(3) + F(4) = 5
F(6) = F(4) + F(5) = 8
Hence, the 6th Fibonacci number is 8.

The Fibonacci sequence follows the recurrence relation: F(n)=F(n−1)+F(n−2). A straightforward recursive solution repeatedly solves the same subproblems, resulting in exponential time complexity. Dynamic programming improves this to O(n) time. The Fast Doubling Method further reduces the time complexity to O(log n).

Using Recursive Fast Doubling - O(log n) Time and O(log n) Space

The idea is to recursively compute F(k) and F(k + 1), where k = n / 2, and use the Fast Doubling formulas to obtain F(n) directly.

Why does this approach work?

The approach is based on the following Fast Doubling formulas:

  • Even index: F(2n) = F(n) * (2F(n + 1) - F(n))
  • Odd index: F(2n + 1) = F(n) ^ 2 + F(n + 1) ^ 2

These identities allow us to compute the Fibonacci number for a larger index directly from two smaller Fibonacci numbers, reducing the problem size by half in each recursive call. This is why the Fast Doubling Method runs in O(log n) time.

Working of Approach:

  • If n = 0, return F(0) = 0 and F(1) = 1.
  • Recursively compute F(k) and F(k + 1), where k = n / 2.
  • Use the Fast Doubling formulas to compute F(2k) and F(2k + 1).
  • If n is even, return F(2k); otherwise, return F(2k + 1).

Let us consider n = 6.

  • Firstly, fastDoubling(6) calls fastDoubling(3) to compute F(3) and F(4).
  • Then, fastDoubling(3) calls fastDoubling(1), which further calls fastDoubling(0). The base case returns (0, 1).
  • Using (0, 1), fastDoubling(1) computes (1, 1), representing (F(1), F(2)).
  • Using (1, 1), fastDoubling(3) computes (2, 3), representing (F(3), F(4)).
  • Using (2, 3), fastDoubling(6) computes (8, 13), representing (F(6), F(7)).
  • Finally, the first value of the pair, 8, is returned as the 6th Fibonacci number.
C++
#include <iostream>
using namespace std;

const int MOD = 1000000007;

// Function returns {F(n), F(n + 1)}
pair<int, int> fastDoubling(int n)
{
    // Base Case
    if (n == 0)
        return {0, 1};

    // Recursively find F(k) and F(k + 1)
    auto p = fastDoubling(n / 2);

    int a = p.first;
    int b = p.second;

    // Compute F(2k)
    int c = (1LL * a * ((2LL * b % MOD - a + MOD) % MOD)) % MOD;

    // Compute F(2k + 1)
    int d = (1LL * a * a + 1LL * b * b) % MOD;

    // If n is even
    if (n % 2 == 0)
        return {c, d};

    // If n is odd
    return {d, (c + d) % MOD};
}

int nthFibonacci(int n)
{
    // Return the n-th Fibonacci number
    return fastDoubling(n).first;
}

int main()
{
    int n = 6;
    cout << "F(" << n << ") = " << nthFibonacci(n) << "\n";
    return 0;
}
Java
import java.util.Arrays;

public class GFG {
    static final int MOD = 1000000007;

    // Function returns {F(n), F(n + 1)}
    static int[] fastDoubling(int n)
    {
        // Base Case
        if (n == 0)
            return new int[] { 0, 1 };

        // Recursively find F(k) and F(k + 1)
        int[] p = fastDoubling(n / 2);

        int a = p[0];
        int b = p[1];

        // Compute F(2k)
        int c = (int)((1L * a
                       * ((2L * b % MOD - a + MOD) % MOD))
                      % MOD);

        // Compute F(2k + 1)
        int d = (int)((1L * a * a + 1L * b * b) % MOD);

        // If n is even
        if (n % 2 == 0)
            return new int[] { c, d };

        // If n is odd
        return new int[] { d, (c + d) % MOD };
    }

    static int nthFibonacci(int n)
    {
        // Return the n-th Fibonacci number
        return fastDoubling(n)[0];
    }

    public static void main(String[] args)
    {
        int n = 6;
        System.out.println("F(" + n
                           + ") = " + nthFibonacci(n));
    }
}
Python
MOD = 1000000007

# Function returns {F(n), F(n + 1)}


def fastDoubling(n):
    # Base Case
    if n == 0:
        return (0, 1)

    # Recursively find F(k) and F(k + 1)
    p = fastDoubling(n // 2)

    a = p[0]
    b = p[1]

    # Compute F(2k)
    c = (a * ((2 * b % MOD - a + MOD) % MOD)) % MOD

    # Compute F(2k + 1)
    d = (a * a + b * b) % MOD

    # If n is even
    if n % 2 == 0:
        return (c, d)

    # If n is odd
    return (d, (c + d) % MOD)


def nthFibonacci(n):
    # Return the n-th Fibonacci number
    return fastDoubling(n)[0]


if __name__ == "__main__":
    n = 6
    print(f"F({n}) = {nthFibonacci(n)}")
C#
using System;

public class GFG {
    const int MOD = 1000000007;

    // Function returns {F(n), F(n + 1)}
    static(int, int) FastDoubling(int n)
    {
        // Base Case
        if (n == 0)
            return (0, 1);

        // Recursively find F(k) and F(k + 1)
        var p = FastDoubling(n / 2);

        int a = p.Item1;
        int b = p.Item2;

        // Compute F(2k)
        int c = (int)((1L * a
                       * ((2L * b % MOD - a + MOD) % MOD))
                      % MOD);

        // Compute F(2k + 1)
        int d = (int)((1L * a * a + 1L * b * b) % MOD);

        // If n is even
        if (n % 2 == 0)
            return (c, d);

        // If n is odd
        return (d, (c + d) % MOD);
    }

    static int NthFibonacci(int n)
    {
        // Return the n-th Fibonacci number
        return FastDoubling(n).Item1;
    }

    public static void Main()
    {
        int n = 6;
        Console.WriteLine("F(" + n
                          + ") = " + NthFibonacci(n));
    }
}
JavaScript
const MOD = 1000000007;

// Function returns {F(n), F(n + 1)}
function fastDoubling(n)
{
    // Base Case
    if (n === 0)
        return [ 0, 1 ];

    // Recursively find F(k) and F(k + 1)
    const p = fastDoubling(Math.floor(n / 2));

    let a = p[0];
    let b = p[1];

    // Compute F(2k)
    let c = (BigInt(a)
             * ((BigInt(2) * BigInt(b) % BigInt(MOD)
                 - BigInt(a) + BigInt(MOD))
                % BigInt(MOD)))
            % BigInt(MOD);

    // Compute F(2k + 1)
    let d = (BigInt(a) * BigInt(a) + BigInt(b) * BigInt(b))
            % BigInt(MOD);

    // If n is even
    if (n % 2 === 0)
        return [ Number(c), Number(d) ];

    // If n is odd
    return [ Number(d), (Number(c) + Number(d)) % MOD ];
}

function nthFibonacci(n)
{
    // Return the n-th Fibonacci number
    return fastDoubling(n)[0];
}

// Driver Code
const n = 6;
console.log(`F(${n}) = ${nthFibonacci(n)}`);

Output
F(6) = 8

Using Iterative Fast Doubling - O(log n) Time and O(log n) Space

The idea is to process the binary representation of N from left to right and use the Fast Doubling formulas to iteratively update two consecutive Fibonacci numbers. Since each bit is processed once, the algorithm computes the N-th Fibonacci number efficiently.

Why does this approach work?

The approach maintains the invariant that the array f = [F(i), F(i + 1)] always stores two consecutive Fibonacci numbers for the current index i.

For every bit of n:

  • If the current bit is 0, we update f to [F(2i), F(2i + 1)].
  • If the current bit is 1, we update f to [F(2i + 1), F(2i + 2)].

Since every binary digit of n is processed exactly once, after processing all bits, f[0] becomes F(n).

Working of Approach:

  • Initialize f = [0, 1], representing F(0) and F(1).
  • Convert N into its binary representation.
  • Traverse the bits from left to right.
  • Apply the Fast Doubling formulas to update f based on the current bit.
  • After all bits are processed, return f[0].

Let us consider n = 6.
Binary representation of 6 is 110.

  • Initial: f = [0, 1] -> (F(0), F(1))
  • Bit = 1: f = [1, 1] -> (F(1), F(2))
  • Bit = 1: f = [2, 3] -> (F(3), F(4))
  • Bit = 0: f = [8, 13] -> (F(6), F(7))

Hence, the 6th Fibonacci number is 8.

C++
#include <bitset>
#include <iostream>
#include <string>
using namespace std;

// Function to convert decimal number to binary string
string decimalToBinary(int n)
{

    string bin = bitset<32>(n).to_string();

    int pos = bin.find('1');

    if (pos != string::npos)
        return bin.substr(pos);

    return "0";
}

// Function to find the N-th Fibonacci number
int nthFibonacci(int n)
{

    string bits = decimalToBinary(n);

    // f[0] = F(i), f[1] = F(i + 1)
    int f[2] = {0, 1};

    for (char bit : bits)
    {

        // Compute F(2i)
        int f2i = 1LL * f[0] * (2 * f[1] - f[0]);

        // Compute F(2i + 1)
        int f2i1 = 1LL * f[0] * f[0] + 1LL * f[1] * f[1];

        if (bit == '0')
        {
            f[0] = f2i;
            f[1] = f2i1;
        }
        else
        {
            f[0] = f2i1;
            f[1] = f2i + f2i1;
        }
    }

    return f[0];
}

int main()
{
    int n = 6;
    cout << "F(" << n << ") = " << nthFibonacci(n);
    return 0;
}
Java
import java.util.Arrays;

public class GFG {
    // Function to convert decimal number to binary string
    public static String decimalToBinary(int n)
    {
        String bin = Integer.toBinaryString(n);
        int pos = bin.indexOf('1');
        if (pos != -1) {
            return bin.substring(pos);
        }
        return "0";
    }

    // Function to find the N-th Fibonacci number
    public static int nthFibonacci(int n)
    {
        String bits = decimalToBinary(n);
        // f[0] = F(i), f[1] = F(i + 1)
        int[] f = { 0, 1 };
        for (char bit : bits.toCharArray()) {
            // Compute F(2i)
            int f2i = f[0] * (2 * f[1] - f[0]);
            // Compute F(2i + 1)
            int f2i1 = f[0] * f[0] + f[1] * f[1];
            if (bit == '0') {
                f[0] = f2i;
                f[1] = f2i1;
            }
            else {
                f[0] = f2i1;
                f[1] = f2i + f2i1;
            }
        }
        return f[0];
    }

    public static void main(String[] args)
    {
        int n = 6;
        System.out.println("F(" + n
                           + ") = " + nthFibonacci(n));
    }
}
Python
def decimalToBinary(n):
    bin = bin(n)[2:]
    pos = bin.find('1')
    if pos != -1:
        return bin[pos:]
    return '0'


def nthFibonacci(n):
    bits = decimalToBinary(n)
    # f[0] = F(i), f[1] = F(i + 1)
    f = [0, 1]
    for bit in bits:
        # Compute F(2i)
        f2i = f[0] * (2 * f[1] - f[0])
        # Compute F(2i + 1)
        f2i1 = f[0] * f[0] + f[1] * f[1]
        if bit == '0':
            f[0] = f2i
            f[1] = f2i1
        else:
            f[0] = f2i1
            f[1] = f2i + f2i1
    return f[0]


if __name__ == '__main__':
    n = 6
    print(f'F({n}) = {nthFibonacci(n)}')
C#
using System;

public class GFG {
    // Function to convert decimal number to binary string
    public static string DecimalToBinary(int n)
    {
        string bin = Convert.ToString(n, 2);
        int pos = bin.IndexOf('1');
        if (pos != -1)
            return bin.Substring(pos);
        return "0";
    }

    // Function to find the N-th Fibonacci number
    public static int NthFibonacci(int n)
    {
        string bits = DecimalToBinary(n);
        // f[0] = F(i), f[1] = F(i + 1)
        int[] f = { 0, 1 };
        foreach(char bit in bits)
        {
            // Compute F(2i)
            int f2i = f[0] * (2 * f[1] - f[0]);
            // Compute F(2i + 1)
            int f2i1 = f[0] * f[0] + f[1] * f[1];
            if (bit == '0') {
                f[0] = f2i;
                f[1] = f2i1;
            }
            else {
                f[0] = f2i1;
                f[1] = f2i + f2i1;
            }
        }
        return f[0];
    }

    public static void Main()
    {
        int n = 6;
        Console.WriteLine("F(" + n
                          + ") = " + NthFibonacci(n));
    }
}
JavaScript
function decimalToBinary(n)
{
    let bin = n.toString(2);
    let pos = bin.indexOf("1");
    if (pos !== -1) {
        return bin.substring(pos);
    }
    return "0";
}

function nthFibonacci(n)
{
    let bits = decimalToBinary(n);
    // f[0] = F(i), f[1] = F(i + 1)
    let f = [ 0, 1 ];
    for (let bit of bits) {
        // Compute F(2i)
        let f2i = f[0] * (2 * f[1] - f[0]);
        // Compute F(2i + 1)
        let f2i1 = f[0] * f[0] + f[1] * f[1];
        if (bit === "0") {
            f[0] = f2i;
            f[1] = f2i1;
        }
        else {
            f[0] = f2i1;
            f[1] = f2i + f2i1;
        }
    }
    return f[0];
}

// Driver Code
let n = 6;
console.log(`F(${n}) = ${nthFibonacci(n)}`);

Output
F(6) = 8

Note: The auxiliary space can be reduced to O(1) by processing the bits of n directly instead of first converting it into a binary string.

Comment