See the previous and initial iteration.
I have incorporated almost all the suggestions by Peter Taylor:
- The actual method returns a
BigIntegerinstead ofString. - The actual method can deal with Fibonacci numbers with negative indices, so there is no any need to throw
IllegalArgumentException. - The only base case that is checked is \$n = 0\$.
fibonacciMatrixrenamed topow.mainis now more sensible.
(The matrix power method is still recursive.)
See what I have:
import java.math.BigInteger;
public class LargeFibonacciNumbers {
public static BigInteger fibonacci(int n) {
if (n == 0) {
return BigInteger.ZERO;
}
BigInteger[][] matrix = new BigInteger[2][2];
matrix[0][0] = BigInteger.ONE;
matrix[0][1] = BigInteger.ONE;
matrix[1][0] = BigInteger.ONE;
matrix[1][1] = BigInteger.ZERO;
BigInteger tmp = pow(matrix, Math.abs(n))[0][1];
if (n > 0 || ((n & 1) == 1)) {
return tmp;
} else {
return tmp.negate();
}
}
private static BigInteger[][] multiply(BigInteger[][] matrix1,
BigInteger[][] matrix2) {
BigInteger[][] ret = new BigInteger[2][2];
ret[0][0] = matrix1[0][0].multiply(matrix2[0][0])
.add(matrix1[0][1].multiply(matrix2[1][0]));
ret[0][1] = matrix1[0][0].multiply(matrix2[0][1])
.add(matrix1[0][1].multiply(matrix2[1][1]));
ret[1][0] = matrix1[1][0].multiply(matrix2[0][0])
.add(matrix1[1][1].multiply(matrix2[1][0]));
ret[1][1] = matrix1[1][0].multiply(matrix2[0][1])
.add(matrix1[1][1].multiply(matrix2[1][1]));
return ret;
}
private static BigInteger[][] pow(BigInteger[][] matrix, int n) {
if (n == 1) {
// End the recursion.
return matrix;
}
BigInteger[][] tmp = pow(matrix, n >> 1);
tmp = multiply(tmp, tmp);
if ((n & 1) == 1) {
tmp = multiply(matrix, tmp);
}
return tmp;
}
public static void main(String[] args) {
if (args.length > 0) {
int n;
try {
n = Integer.parseInt(args[0]);
} catch (NumberFormatException ex) {
System.err.println("Could not parse \"" + args[0] +
"\" as an integer.");
return;
}
System.out.println(fibonacci(n));
} else {
System.out.println("Usage: java -jar File.jar N");
System.out.println("Where N is the index of the Fibonacci number " +
"to compute.");
}
}
}
So, what do you think?
[1][0]and using item[0][1]instead. \$\endgroup\$