1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
#pragma warning(disable: 4624 4715)
// https://github.com/catchorg/Catch2
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
#include <stdint.h>
#include <vector>
const int fib_numbers[] = { 0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765};
const int N = sizeof(fib_numbers) / sizeof(fib_numbers[0]);
unsigned long long fib1(int n) // rolling sequence of 3
{
if (n <= 1) return n;
unsigned long long a = 0, b = 1, c = a + b;
for (int i = 3; i <= n; i++)
{
a = b;
b = c;
c = a + b;
}
return c;
}
unsigned long long fib2(int n) // use a vector
{
if (n <= 1) return n;
std::vector<unsigned long long> F(n + 1);
F[0] = 0; F[1] = 1;
for (int i = 2; i <= n; i++) F[i] = F[i - 1] + F[i - 2];
return F[n];
}
unsigned long long fib3(int n) // exact solution of difference equation
{
const double phi1 = 0.5 * (sqrt(5) + 1), phi2 = phi1 - 1;
if (n <= 1) return n;
int s = 1; if (n % 2) s = -1;
unsigned long long F = 0.5 + (pow(phi1, n) - s * pow(phi2, n)) / (phi1 + phi2);
return F;
}
TEST_CASE("Fib1")
{
BENCHMARK("Fib1");
for (int i = 0; i < N; i++)
{
CHECK(fib1(i) == fib_numbers[i]);
}
}
TEST_CASE("Fib2")
{
BENCHMARK("Fib2");
for (int i = 0; i < N; i++)
{
CHECK(fib2(i) == fib_numbers[i]);
}
}
TEST_CASE("Fib3")
{
BENCHMARK("Fib3");
for (int i = 0; i < N; i++)
{
CHECK(fib2(i) == fib_numbers[i]);
}
}
|