'Very Large Fibonacci in Java

I am trying to rapidly calculate large Fibonacci numbers. Here is my code. It is prohibitively slow for numbers above 1 million, how can it be improved?

public static BigInteger fib(BigInteger n) {

        int k = n.intValue();
        BigInteger ans = null;

        if(k == 0) { 
            ans = new BigInteger("0");
        } else if(Math.abs(k) <= 2) {
            ans = new BigInteger("1");
        } else {
            BigInteger km1 = new BigInteger("1");
            BigInteger km2 = new BigInteger("1");

            for(int i = 3; i <= Math.abs(k); ++i) {
                ans = km1.add(km2);
                km2 = km1;
                km1 = ans;
            }
        }

       if(k<0 && k%2==0) { ans = ans.negate(); }
       return ans;
    } 

Binet's worked well. Thanks guys!



Solution 1:[1]

static void multiply(BigInteger m[][], BigInteger n[][]) {
    BigInteger a = (m[0][0].multiply(n[0][0])).add(m[0][1].multiply(n[1][0]));
    BigInteger b = (m[0][0].multiply(n[0][1])).add(m[0][1].multiply(n[1][1]));
    BigInteger c = (m[1][0].multiply(n[0][0])).add(m[1][1].multiply(n[0][1]));
    BigInteger d = (m[1][0].multiply(n[0][1])).add(m[1][1].multiply(n[1][1]));
    m[0][0] = a;
    m[0][1] = b;
    m[1][0] = c;
    m[1][1] = d;
}

static void fib(int x) {
    BigInteger m[][] = new BigInteger[2][2];
    m[0][0] = new BigInteger("1");
    m[0][1] = new BigInteger("1"); //f1
    m[1][0] = new BigInteger("1");
    m[1][1] = new BigInteger("0");

    BigInteger n[][] = new BigInteger[2][2];
    n[0][0] = new BigInteger("1");
    n[0][1] = new BigInteger("1"); //f1
    n[1][0] = new BigInteger("1");
    n[1][1] = new BigInteger("0");

    int i = x;
    ArrayList <Integer> a = new ArrayList<>();
    while (i != 1) {
        if (i%2 == 0) {
            a.add(0);
            i = i / 2;
        } else {
            a.add(1);
            i = i / 2;
        }
    }
    for (int j = a.size() - 1; j >= 0 ; j--) {
        if (a.get(j) == 0) {
            multiply(m, m);
        } else {
            multiply(m, m);
            multiply(m, n);
        }
    }
    System.out.println(m[1][0]);
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Victor