1+ package main .java .videos ;
2+
3+ import java .util .Arrays ;
4+
5+ public class FibonacciNumbers {
6+ public static void main (String [] args ) {
7+ final FibonacciFinder fibonacciFinder = new FibonacciFinder ();
8+ for (int i = 0 ; i < 15 ; i ++) {
9+ System .out .println (fibonacciFinder .fib (i ));
10+ }
11+ }
12+ }
13+
14+ class FibonacciFinder {
15+ private final long [][][] exponents ;
16+
17+ public FibonacciFinder () {
18+ exponents = new long [64 ][2 ][2 ];
19+ exponents [0 ] = new long [][]{{1 , 1 }, {1 , 0 }};
20+ for (int i = 1 ; i < exponents .length ; i ++) {
21+ exponents [i ] = square (exponents [i - 1 ]);
22+ }
23+ }
24+
25+ private long [][] square (final long [][] matrix ) {
26+ return multiply (matrix , matrix );
27+ }
28+
29+ private long [][] multiply (final long [][] matrix1 , final long [][] matrix2 ) {
30+ final long [][] result = new long [matrix1 [0 ].length ][matrix2 .length ];
31+ for (int i = 0 ; i < matrix1 .length ; i ++) {
32+ for (int j = 0 ; j < matrix2 [0 ].length ; j ++) {
33+ for (int k = 0 ; k < matrix1 [i ].length ; k ++) {
34+ result [i ][j ] += matrix1 [i ][k ] * matrix2 [k ][j ];
35+ }
36+ }
37+ }
38+ return result ;
39+ }
40+
41+ public long fib (int n ) {
42+ if (n < 0 ) {
43+ throw new IllegalArgumentException ();
44+ } else if (n == 0 || n == 1 ) {
45+ return 1 ;
46+ } else {
47+ final long [][] matrix = binaryExponentiation (n - 1 );
48+ return matrix [0 ][0 ] + matrix [0 ][1 ];
49+ }
50+ }
51+
52+ private long [][] binaryExponentiation (final int n ) {
53+ long [][] result = new long [][]{{1 , 0 }, {0 , 1 }};
54+ for (int i = 31 ; i >= 0 ; i --) {
55+ if ((n & (1 << i )) != 0 ) {
56+ result = multiply (result , exponents [i ]);
57+ }
58+ }
59+ return result ;
60+ }
61+ }
0 commit comments