47 lines
1.4 KiB
C
47 lines
1.4 KiB
C
#include <stdio.h>
|
|
#include <stdint.h>
|
|
|
|
// tiny struct to hold a 2x2 matrix
|
|
typedef struct {
|
|
uint64_t m00, m01, m10, m11;
|
|
} Matrix2x2;
|
|
|
|
// multiply two 2x2 matrices together
|
|
Matrix2x2 multiply(Matrix2x2 a, Matrix2x2 b) {
|
|
// standard 2x2 matrix multiplication
|
|
return (Matrix2x2) {
|
|
a.m00* b.m00 + a.m01 * b.m10, // top-left
|
|
a.m00* b.m01 + a.m01 * b.m11, // top-right
|
|
a.m10* b.m00 + a.m11 * b.m10, // bottom-left
|
|
a.m10* b.m01 + a.m11 * b.m11 // bottom-right
|
|
};
|
|
}
|
|
|
|
// raise a matrix to the power n using binary exponentiation
|
|
Matrix2x2 matrix_pow(Matrix2x2 base, int n) {
|
|
Matrix2x2 result = { 1, 0, 0, 1 }; // start with identity
|
|
while (n > 0) {
|
|
if (n % 2 == 1) result = multiply(result, base); // if odd, multiply once
|
|
base = multiply(base, base); // square the base
|
|
n /= 2; // integer divide n by 2
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// get nth fibonacci number using matrix exponentiation
|
|
uint64_t fibonacci_matrix(int n) {
|
|
if (n == 0) return 0; // edge case
|
|
Matrix2x2 base = { 1, 1, 1, 0 }; // Fibonacci Q-matrix
|
|
Matrix2x2 result = matrix_pow(base, n - 1); // raise to (n-1)
|
|
return result.m00; // top-left is F(n)
|
|
}
|
|
|
|
int main() {
|
|
int n = 50; // how many numbers to print
|
|
for (int i = 0; i < n; i++) {
|
|
printf("%llu ", fibonacci_matrix(i)); // print each fib number
|
|
}
|
|
printf("\n"); // newline at end
|
|
return 0;
|
|
}
|