Blog Archive

Friday, May 2, 2014

Fibonacci Sequence - Very Long Number Adressing

http://jencropable.com/the-fibonacci-spiral/


I've always heard about sequences, the most famous is "the Fibonacci Sequence", and almost everyone've heard about the starting terms 0, 1, 1, 2, 3, 5, etc. Basically, the first term plus the second results in the third one, the second plus the third results in the fourth one, etc.

There is also a way to calculate any term based on the golden ratio:



If you want to know more about this sequence you can google it or visit this link:
http://en.wikipedia.org/wiki/Fibonacci_number

The problem is that if you want to know a very high term there is no way for a numeric type, on programming languages, to address it.

The solution to this problem is simple, if you want to know the term 1.000.000th first you have to estimate how many digits it has, to know the size of an array to store it, using the UInt64 type as a 19 digit handler (because it can not store the 20 digits number 99.999.999.999.999.999.999) you just need to split the number every 19 digits. 

So, for a 20 digits number you need a length 2 array (at least), to store 19 digits in the last position and 1 digit in the first position (keeping the order). The 1.000.000th term has 207.505 digits, so you should use a 10.922 length array.

Steps:




First: Use the "golden ratio based method" to instantly show the terms (for numbers below the 93rd term).
Second: Use a two* dimensional array to split the longer numbers using the regular method (adding the last 2 terms).

* : Two dimensions because you need to store two terms plus an auxiliar. You can also use three unidimesional arrays.

Why not List?
Array are way faster than Lists for calculations, around N to N^2 times for very long numbers.

What would this work for?
There is a lot of very useful applications, you can use it to implement a random number generator for example.

How does it work?
I use this method:

digits = term * 0.20898438
array length = ( digits / 19 ) + 1

so:

array length = 1 + term * 0.010999

So if you want to know the term 3.000.000th it should have no more than 626.955 digits, so you need a 32.998 length array (at least).

There should be a better, and more precise, way to get the number of digits, you should google it if you want to know, but I find this number by analizing the terms I got. 

Have fun and enjoy.
(This is a C# code) 

using System;
using System.Diagnostics;
namespace ConsoleApplication1
{
    class Program
    {
        static void GetFibonacci (int datoLeido)
        {
            int digitos = 0;
            int largo = (int)(1 + 0.010999 * datoLeido);
            Stopwatch sw = new Stopwatch();
            UInt64[,] fibonacci = new UInt64[largo , 3];
                if (datoLeido <= 93)
                {
                    fibonacci [0, 0] = (UInt64)(Math.Pow ((1 + Math.Sqrt (5)) / 2, datoLeido) / Math.Sqrt (5) - Math.Pow ((1 - Math.Sqrt (5)) / 2, datoLeido) / Math.Sqrt (5));
                    Console.WriteLine ("Term: " + fibonacci [0, 0]);
                    Console.WriteLine ("Press any key to continue...");
                    Console.ReadKey ();
                }
                else
                {
                    sw.Start ();
                    fibonacci [fibonacci.GetLength (0) - 1, 0] = (UInt64)(Math.Pow ((1 + Math.Sqrt (5)) / 2, 91) / Math.Sqrt (5) - Math.Pow ((1 - Math.Sqrt (5)) / 2, 91) / Math.Sqrt (5));
                    fibonacci [fibonacci.GetLength (0) - 1, 1] = (UInt64)(Math.Pow ((1 + Math.Sqrt (5)) / 2, 92) / Math.Sqrt (5) - Math.Pow ((1 - Math.Sqrt (5)) / 2, 92) / Math.Sqrt (5));
                    for (int j = 0; j <= datoLeido - 93; j++)
                    {
                        for (int i = fibonacci.GetLength (0) - 1; i >= 0; i--)
                        {
                            fibonacci [i, 2] = fibonacci [i, 1];
                            if (fibonacci [i, 1] == 0)
                                break;
                        }
                        for (int i = fibonacci.GetLength (0) - 1; i > 0; i--)
                        {
                            fibonacci [i, 1] += fibonacci [i, 0];
                            fibonacci [i - 1, 1] += fibonacci [i, 1] / 10000000000000000000;
                            fibonacci [i, 1] = fibonacci [i, 1] % 10000000000000000000;
                            if (fibonacci [i, 1] == 0)
                                break;
                        }
                        for (int i = fibonacci.GetLength (0) - 1; i >= 0; i--)
                        {
                            fibonacci [i, 0] = fibonacci [i, 2];
                            if (fibonacci [i, 2] == 0)
                                break;
                        }  
                    }
                    sw.Stop ();
                    Console.WriteLine ("Term: ");
                    for (int i = 0; i < fibonacci.GetLength (0); i++)
                    {
                        if (fibonacci [i, 1] != 0)
                        {
                            Console.Write (fibonacci [i, 1]);
                            digitos = digitos + fibonacci [i, 1].ToString ().Length;
                        }
                    }
                    Console.WriteLine ();
                    Console.WriteLine ("Digits: " + digitos);
                    Console.WriteLine ("Elapsed time: " + sw.Elapsed);
                    Console.Write ("Press a key to continue...");
                    Console.ReadKey ();
                }
        }

        static void Main(string[] args)
        {
            string datoLeido;
            int dl;
            do
            {  
                Console.Clear();
                Console.WriteLine ("Fibonacci Sequence");
                Console.WriteLine ("Enter the term you want to know? [X: Exit]");
                datoLeido = Console.ReadLine();
                if(int.TryParse(datoLeido, out dl))
                    GetFibonacci(dl);
                else
                    if(datoLeido.ToUpper()!="X")
                        Console.Write (" ¬¬ It should be an integer number...");
            }while(datoLeido.ToUpper()!="X");
        }
    }
}

1 comment:

  1. 100th
    354224848179262988288

    1.000th
    4346410180326543836845087314016942854294609804338179020004506363684880489277264714682006629114397086613858791520866180411962144865917790109120787393014469589712725227814427628000993082872107351426370412544

    10.000th
    17188052238895888749957510829161024460725068757005044280986804544568171242041800492423010169253671520173884136610843646513483210056678972064805552892670913905786959989568341158340408472849132831669154860317029511625078548807328891998095014065243904120683240839852724185930779756992465477698716828134751829638978259937341588336192167076077997381584428891206923325551894951848259725302155004365353768265910099255901018696707204805628826753197803495075644740826241815524197641063129865861738085519825616660361717310530339654782419205910296119646972478090440198297808062125481161137736586917404606976464088001047966446169825360484052794468070675891173143427474306887241513006087120191316857717862219695130919808925144170176099111367220717687053698550765844647419227758575245195789520291560256944682270480372530900026325306781770665572528083893172703129873881140896430772186383424389348049970720800189068247279833274511092797322508594217934076214376698405239799513167648092006025681664109550725834455979428561242484891916396529692956584029429337819934904110514639688176589833400610023017596318370417964904799519314734368839169852671668875138664458841847262644839897173884233623736594291454601431140043597960762069959976183737354078888929014987218235034226290958529890005742176396068203585745322221367882086654734856733880059093797015991435864888568668580912930805169646720227056284394546927163373962353001125182069839264601936760270191198448424529959252855531604905867655908962983276945024140055144510635884377455707386938579876582488365951695039083337417846611434424593793747481237136266626825433549476736150522997538128678182523320534989971829414102795492713582355241231903170693281728063227333349633716961375254801122253288943407321591227738481125308637926633369212163221676251149924052486858709616932749047778471207633521478056983304908222336216333378634979409704946784034433881461609340707846995868157108243715605761457409891075529397574411843675372128179386473847877169840543289068760443237843873469225168428986142948823060053737066539224497179077308355243815254843627118592

    ReplyDelete