When Augusta Ada King, the Countess of Lovelace was working on her documentation, somehow winning her the fame of the first programmer in human history, with regards to the algorithmic design for Babbage's analytical machine which never got realized in either of their lives, one of the algorithm she dealt with was actually about generating Fibonacci sequences. The algorithm itself is trivial in a modern programmer's eye, and is almost a sign of incompetency for any student majoring in computing who is not up to it, however work and the related findings laid the foundation of computing science, witnessed the early stage of human investigation into these disciplines and the historical value of it is remarkably significant.
As part of the study of ADA programming language, and as a means of celebrating Ada's 196th anniversary (HAPPY BIRTHDAY, HER GRACE, MADAM ADA KING) and commemorating her for all the contributions she made in her short life to computer science and technology, I would type in a few lines showing how to do Fibonacci with integer values whose data structure is specially designed for holding extremely large, almost unlimited integer values.
After a bit of look at the first few items of the sequence, you may find, the sequence quickly runs beyond representation of the 32bit and even the 64bit integer type in a digital computer. That's where a special big integer type comes in. C# (and probably Java) has got such data types predefined. Not sure if ADA has an existing or not, I feel it's not hard as well as it is fun to create one for such a strongly typed language as ADA that has a huge capacity and capability of describing data structures.
What I chose to do this time was to create the seemingly unlimited big integer type with unconstrained arrays contained in a structure. It is not strange to see such things as an array here, as far as an integer type that can grow on demand is concerned.
So what comes first is the declaration of the big integer package with the data types and operations in it. That's something like below, which is a complete copy of the current version of the source code of the project hosted on google code as https://ariane.googlecode.com/svn/trunk/.
generic
type length_t is range<>;
package ariane.numerics.biginteger is
-- object type is an indefinite private record
type object(n : length_t) is private;
-- array storing components of the numbers as its elements
type cells_t is array(length_t range <>) of integer;
type objectptr is access all object;
-- creates a big integer object on stack
function create(cells : cells_t) return object;
-- creates a big integer object on heap with value given by the argument
function create(o : object) return objectptr;
-- destroys the big integer object created on heap
procedure free(p : in out objectptr);
-- gets the string represtentation of the big integer object
function tostring(o : in object) return string;
-- operators on big integer objects
function "+"(lhs, rhs : in object) return object;
function "-"(lhs, rhs : in object) return object;
private
type cells_access is access all cells_t;
-- each cell in the array accounts for certain portion of the number
-- by representing corresponding digits in the number in decimal format
-- and maximum of it is biggest possible multiple of 10 held by
-- 32-bit integer minus one, i.e. 1000000000 - 1 = 999999999
maxmulten : constant integer := 1000000000;
maxcellval : constant integer := maxmulten - 1;
maxdigitspercell : constant integer := 9;
type object (n : length_t) is record
-- array that store the data that represents the integer value
cells : cells_t(1..n);
actln : length_t; -- effective length of the array
end record;
end ariane.numerics.biginteger;
As you can see it's a generic package with a generic argument that specifies an unconstrained range type that is used just for representing size and index of the arrays for storing data of big integer number. The central type of big integer is named object as a usual and suggestible practice. The object is an unconstrained and indefinite (as it has no default value for its argument) type. So the only way for an external user to instantiate it (on the stack) is through a subprogram like the create method shown above. There are two operators namely add and subtract that are defined on the object. The corresponding access type of the object type is also defined as named type so as to be able to be used by different part of the program. The access type along with the allocation method also named create enables the object to be created on heap accessed and manipulated with a pointer (access). So essentially this unit provides two ways of instantiating and manipulating the big integer number objects. One thing worth noting is that as a discriminated record (discriminated by an ordinal number to vary the length of the array inside) the discriminator of the type which is n is this case is also part of the record, which is natural enough, and the reason why we may need an extra field called actln here to store the actual number of items in the array that is used for storing the nontrivial parts of the number is we may still allow certain circumstances where the number is not stored using an array as shortest in length as possible and such a representation is needed (although we may at best eventually exclude all such uncompacted numbers from external users). There are also some numeric constants whose meanings are described by the comments and will shortly be seen and discussed in the following article regarding the implementation.