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