Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Использование комплексных чисел для вычисления Fn красиво с математической точки зрения, но уродливо — с компьютерной.
Хорошее:Ну сколько же можно. Где там логарифмическое время? Ну невозможно умножать за логарифмическое время. Длина байтового представления n-го числа Фиббоначи растет линейно. В uint64 влезет 93е (если не ошибаюсь) число фиббоначи, кешируется все это в 0.7Кб, т.е. на практике сложность или константная (если нам надо числа до определенного) или уж никак ни логарифмическая, коли даже битовое представление числа уже линейно растет, не говоря уже про умножение.
Фиксированный объём памяти, логарифмическое время
Тем, что возведение в степень можно произвести за логарифмическое время.То что работает в рамках 64 битных регистров нельзя переносить на большие числа. Правильнее было бы сказать что в целую степень можно возвести за логарифмическое количество умножений.

fib 0 = 0
fib 1 = 1
fib nn = if even nn
then let n = div nn 2 in
(2 * fib (n - 1) + fib n) * fib n
else let n = div (nn+1) 2 in
fib n ^ 2 + fib (n-1) ^ 2
using System;
using System.Diagnostics;
using System.Numerics;
namespace ConsoleApplication1
{
class Program
{
public static BigInteger Fib(BigInteger n)
{
if (n < 0)
throw new ArgumentException("The fibo value cannot be negative");
if (n <= 1)
return n;
BigInteger[,] result = { { 1, 0 }, { 0, 1 } };
BigInteger[,] fiboM = { { 1, 1 }, { 1, 0 } };
while (n > 0)
{
if (n%2 == 1)
Mult2x2Matrix(result, fiboM);
n /= 2;
Mult2x2Matrix(fiboM, fiboM);
}
return result[1,0];
}
private static void Mult2x2Matrix(BigInteger[,] m, BigInteger[,] n)
{
BigInteger a = m[0,0] * n[0,0] + m[0,1] * n[1,0];
BigInteger b = m[0,0] * n[0,1] + m[0,1] * n[1,1];
BigInteger c = m[1,0] * n[0,0] + m[1,1] * n[0,1];
BigInteger d = m[1,0] * n[0,1] + m[1,1] * n[1,1];
m[0,0] = a;
m[0,1] = b;
m[1,0] = c;
m[1,1] = d;
}
static void Main(string[] args)
{
var sw = Stopwatch.StartNew();
var bigInteger = Fib(65536);
sw.Stop();
Console.WriteLine("Elapsed milliseconds = {0}, number length = {1} digits", sw.ElapsedMilliseconds, bigInteger.ToString().Length);
}
}
}
5 способов вычисления чисел Фибоначчи: реализация и сравнение