This is the final part of the series, where the details of the code that works on the big integer type to generate Fibonacci sequences are discussed.
With all the basic operations on the big integer type having been elaborated in the package and available for use, the main program can directly use them to perform whatever operations are required in a sequence generation in the manner as it uses objects of ordinary integer types.
The main thing that is left to be figured out is how to instantiate the objects. After a bit of investigation into the type and the possible ways of its being used in a subprogram, one may find that she has to perform an iterative sequence generation in a recursive manner for objects created in declarations (on stack), even if the algorithm can be easily done in a iterative manner. This way, all objects created in the course of the generation process are piled on the stack even if only three objects are actively used in each iteration (for Fibonacci). The only way to improve this, as it seems to me, is allow a stack replacement which is a violation of procedural based programming paradigm. Although the code is by no means efficient, it is very demonstrative for showing how the unconstrained types are used updated and created iteratively in a program (which is not easy to be realized in a consistent manner in C family languages). The variables of the type are used as normal, with the recursive logic (which is neither very easy to figure out nor pleasant to have) being an unavoidable pain.
As an alternative, generation based on dynamic creation of big integer objects on heap is also demonstrated, which is a bit uglier than what is expected since it involves use of pointer, the benefit is that iterative algorithm can be used since objects are created and destroyed appropriately as the process is going.
Below is the code as of writing of this article,
with ariane.numerics.biginteger;
use ariane.numerics;
with ada.text_io;
use ada.text_io;
with ada.strings.Fixed;
use ada.Strings.fixed;
use ada.Strings;
procedure test_numerics_biginteger is
package bigint is new biginteger(length_t=>integer);
use type bigint.object; -- this only works for operators
function fibonacci_onstack(a, b : bigint.object; n : integer)
return bigint.object is
-- initialize both a and b to 1
c : bigint.object := a + b;
begin
if n > 1 then
declare
r : bigint.object := fibonacci_onstack(b, c, n - 1);
begin
return r;
end;
else
return c;
end if;
end fibonacci_onstack;
-- produces and displays fibonacci sequence to the n-th item
-- it is recursively working on stack
procedure fibonacci_onstack(a, b : bigint.object; n : integer) is
c : bigint.object := a + b;
begin
put(trim(integer'image(n), both)); put(": ");
put_line(bigint.tostring(c));
if n > 1 then
fibonacci_onstack(b, c, n - 1);
end if;
end fibonacci_onstack;
procedure fibonacci_onheap(n : integer) is
pa : bigint.objectptr := new bigint.object(1);
pb : bigint.objectptr := new bigint.object(1);
pc : bigint.objectptr;
a : bigint.object := bigint.create((1=>1));
begin
pa.all := a;
pb.all := a;
for i in 1 .. n loop
pc := bigint.create(pa.all + pb.all);
put(trim(integer'image(n-i+1), both)); put(": ");
put_line(bigint.tostring(pc.all));
bigint.free(pa);
pa := pb;
pb := pc;
end loop;
bigint.free(pa);
bigint.free(pb);
end fibonacci_onheap;
-- variable declarations
a : bigint.object := bigint.create((1=>1));
b : bigint.object := a;
begin
fibonacci_onstack(a, b, 200);
fibonacci_onheap(200);
declare
-- note that ADA compiler can differentiate the function call from the
-- procedure call even if their signatures are exactly the same from most
-- other programming languages' perspective
r : bigint.object := fibonacci_onstack(a, b, 200);
begin
put("func call result: ");
put_line(bigint.tostring(r));
end;
end test_numerics_biginteger;
Some programming notes,
1. Again, variables have to be declared and initialized if necessary in the declaration region
2. ADA, as a strictly defined language with great compile time checking, is able to differentiate between procedure and a function with same signature.
3. Some other points are indicated by the comments in the code.
The result of the execution,
200: 2
199: 3
198: 5
197: 8
196: 13
195: 21
194: 34
193: 55
192: 89
191: 144
190: 233
189: 377
188: 610
187: 987
186: 1597
185: 2584
184: 4181
183: 6765
182: 10946
181: 17711
180: 28657
179: 46368
178: 75025
177: 121393
176: 196418
175: 317811
174: 514229
173: 832040
172: 1346269
171: 2178309
170: 3524578
169: 5702887
168: 9227465
167: 14930352
166: 24157817
165: 39088169
164: 63245986
163: 102334155
162: 165580141
161: 267914296
160: 433494437
159: 701408733
158: 1134903170
157: 1836311903
156: 2971215073
155: 4807526976
154: 7778742049
153: 12586269025
152: 20365011074
151: 32951280099
150: 53316291173
149: 86267571272
148: 139583862445
147: 225851433717
146: 365435296162
145: 591286729879
144: 956722026041
143: 1548087559200
142: 2504730781961
141: 4052739537881
140: 6557470319842
139: 10610209857723
138: 17167680177565
137: 27777890035288
136: 44945570212853
135: 72723460248141
134: 117669304609940
133: 190392490709135
132: 308061521170129
131: 498454118792640
130: 806515533049393
129: 1304969544928657
128: 2111485779780500
127: 3416454622906707
126: 5527939700884757
125: 8944394323791464
124: 14472334246762210
123: 23416728348467685
122: 37889062373143906
121: 61305790721611591
120: 99194853947554970
119: 160500643816367088
118: 259695496911122585
117: 420196140727489673
116: 679891637638612258
115: 1100087778366101931
114: 1779979416047141890
113: 2880067194370816120
112: 4660046610375530309
111: 7540113804746346429
110: 12200160415121876738
109: 19740274219868223167
108: 31940434634990099905
107: 51680708854858323072
106: 83621143489848422977
105: 135301852344706746049
104: 218922995834555169026
103: 354224848179261915075
102: 573147844013817084101
101: 927372692193789991760
100: 1500520536206896083277
99: 2427893228399975082453
98: 3928413764606871165730
97: 6356306993006846248183
96: 10284720757613717413913
95: 16641277506200563662096
94: 26925748508234281076009
93: 43566776258854844738105
92: 70492524767089125814114
91: 114059301025943970552219
90: 184551825793033963663330
89: 298611126818977669185520
88: 483162952612010163284885
87: 781774794309870230203437
86: 1264937320429970393488322
85: 2046711111473984623691759
84: 3311648143516982171800810
83: 5358359254990966640871840
82: 8670007398507948658051921
81: 14028366653498915298923761
80: 22698374520068630956975682
79: 36726740705505779255899443
78: 59425114757512643212875125
77: 96151855463018422468774568
76: 155576970220531065681649693
75: 251728825683549488150424261
74: 407305795904080553832073954
73: 659034621587630041982498215
72: 1663404170491710595814572169
71: 1725375039793406370797070384
70: 2791715456571051233611642553
69: 4517090495650391871408712937
68: 7308805952221443105203554900
67: 11825896447871834976429068427
66: 19134702400932780810449423917
65: 30960598847965113057878492344
64: 50953012480583911390327916261
63: 81559000960235041970206408605
62: 131151201344818953360534324866
61: 212207101440105399533740733471
60: 343358302784187294870275058337
59: 555565404224292694404157918080
58: 898923707008479989274290850145
57: 1454489111232772683678306641953
56: 2353412818241252672952597492098
55: 3807901929474253566300904134051
54: 6161314747715278029583501626149
53: 9969216677189303386214405760200
52: 16130531424904581415797907386349
51: 26099748102093884802012313146549
50: 42230279526998466217810220532898
49: 68330276290920351019822533679447
48: 110560307156090817237632754212345
47: 178890334785183168257455287891792
46: 289450641941273985495088421041370
45: 468340976726457153752543329995929
44: 757791618667731139247631372100066
43: 1226132595394188293000174702095995
42: 1983924214061919432247806741960610
41: 3210056809456107725247980776292056
40: 5193981235180270157495786850488117
39: 8404037832974134882743767626780173
38: 13598018856492162402395540477268290
37: 22002056689466296922983322104048463
36: 35600075545958458963222876581316753
35: 57602132235424755886206198685365216
34: 93202207781383214849429075266681969
33: 150804340168079700735635273952047185
32: 244006547798191185585064349218729154
31: 394810887814999156320699623170776339
30: 638817435613190341905763972389505493
29: 1336283230428189498226463595560281832
28: 1672445759413798400132227567949787325
27: 2706074082469569338358691163510069157
26: 4378519841510949178490918731459856482
25: 7845939230980518516849609894969925639
24: 11463113765491467695340528626429782121
23: 18547707689471986212190138521399707760
22: 30108214540963453907530667147829489881
21: 48558529144435440119720805669229197641
20: 78569350599398894027251472817586875220
19: 127127879743834334146972278486287885163
18: 205697230343233228174223751303346572685
17: 332825110087675623210196029789634457848
16: 538522340430300790495419781092981030533
15: 871347450517368352816615810882615488381
14: 1409869790947669143312355919750596518914
13: 2281217241465374961280651402858212007295
12: 3691870324120706639440686994833808526209
11: 5972304273877744135569338397692205335040
10: 9663391306290450775010253925250829059713
9: 15635695580168194910579363790217849593217
8: 25299868864580645685589389182743678652930
7: 40934782466626840596168752972961528246147
6: 66233869353085486281758142155705206899077
5: 107168651819712326877926895128666735145224
4: 173402521172797813159685372843710942044301
3: 280571172992510140037611932413038677189525
2: 453973694165307953197296969697410619233826
1: 734544867157818932349080902110449296423351
200: 2
199: 3
198: 5
197: 8
196: 13
195: 21
194: 34
193: 55
192: 89
191: 144
190: 233
189: 377
188: 610
187: 987
186: 1597
185: 2584
184: 4181
183: 6765
182: 10946
181: 17711
180: 28657
179: 46368
178: 75025
177: 121393
176: 196418
175: 317811
174: 514229
173: 832040
172: 1346269
171: 2178309
170: 3524578
169: 5702887
168: 9227465
167: 14930352
166: 24157817
165: 39088169
164: 63245986
163: 102334155
162: 165580141
161: 267914296
160: 433494437
159: 701408733
158: 1134903170
157: 1836311903
156: 2971215073
155: 4807526976
154: 7778742049
153: 12586269025
152: 20365011074
151: 32951280099
150: 53316291173
149: 86267571272
148: 139583862445
147: 225851433717
146: 365435296162
145: 591286729879
144: 956722026041
143: 1548087559200
142: 2504730781961
141: 4052739537881
140: 6557470319842
139: 10610209857723
138: 17167680177565
137: 27777890035288
136: 44945570212853
135: 72723460248141
134: 117669304609940
133: 190392490709135
132: 308061521170129
131: 498454118792640
130: 806515533049393
129: 1304969544928657
128: 2111485779780500
127: 3416454622906707
126: 5527939700884757
125: 8944394323791464
124: 14472334246762210
123: 23416728348467685
122: 37889062373143906
121: 61305790721611591
120: 99194853947554970
119: 160500643816367088
118: 259695496911122585
117: 420196140727489673
116: 679891637638612258
115: 1100087778366101931
114: 1779979416047141890
113: 2880067194370816120
112: 4660046610375530309
111: 7540113804746346429
110: 12200160415121876738
109: 19740274219868223167
108: 31940434634990099905
107: 51680708854858323072
106: 83621143489848422977
105: 135301852344706746049
104: 218922995834555169026
103: 354224848179261915075
102: 573147844013817084101
101: 927372692193789991760
100: 1500520536206896083277
99: 2427893228399975082453
98: 3928413764606871165730
97: 6356306993006846248183
96: 10284720757613717413913
95: 16641277506200563662096
94: 26925748508234281076009
93: 43566776258854844738105
92: 70492524767089125814114
91: 114059301025943970552219
90: 184551825793033963663330
89: 298611126818977669185520
88: 483162952612010163284885
87: 781774794309870230203437
86: 1264937320429970393488322
85: 2046711111473984623691759
84: 3311648143516982171800810
83: 5358359254990966640871840
82: 8670007398507948658051921
81: 14028366653498915298923761
80: 22698374520068630956975682
79: 36726740705505779255899443
78: 59425114757512643212875125
77: 96151855463018422468774568
76: 155576970220531065681649693
75: 251728825683549488150424261
74: 407305795904080553832073954
73: 659034621587630041982498215
72: 1663404170491710595814572169
71: 1725375039793406370797070384
70: 2791715456571051233611642553
69: 4517090495650391871408712937
68: 7308805952221443105203554900
67: 11825896447871834976429068427
66: 19134702400932780810449423917
65: 30960598847965113057878492344
64: 50953012480583911390327916261
63: 81559000960235041970206408605
62: 131151201344818953360534324866
61: 212207101440105399533740733471
60: 343358302784187294870275058337
59: 555565404224292694404157918080
58: 898923707008479989274290850145
57: 1454489111232772683678306641953
56: 2353412818241252672952597492098
55: 3807901929474253566300904134051
54: 6161314747715278029583501626149
53: 9969216677189303386214405760200
52: 16130531424904581415797907386349
51: 26099748102093884802012313146549
50: 42230279526998466217810220532898
49: 68330276290920351019822533679447
48: 110560307156090817237632754212345
47: 178890334785183168257455287891792
46: 289450641941273985495088421041370
45: 468340976726457153752543329995929
44: 757791618667731139247631372100066
43: 1226132595394188293000174702095995
42: 1983924214061919432247806741960610
41: 3210056809456107725247980776292056
40: 5193981235180270157495786850488117
39: 8404037832974134882743767626780173
38: 13598018856492162402395540477268290
37: 22002056689466296922983322104048463
36: 35600075545958458963222876581316753
35: 57602132235424755886206198685365216
34: 93202207781383214849429075266681969
33: 150804340168079700735635273952047185
32: 244006547798191185585064349218729154
31: 394810887814999156320699623170776339
30: 638817435613190341905763972389505493
29: 1336283230428189498226463595560281832
28: 1672445759413798400132227567949787325
27: 2706074082469569338358691163510069157
26: 4378519841510949178490918731459856482
25: 7845939230980518516849609894969925639
24: 11463113765491467695340528626429782121
23: 18547707689471986212190138521399707760
22: 30108214540963453907530667147829489881
21: 48558529144435440119720805669229197641
20: 78569350599398894027251472817586875220
19: 127127879743834334146972278486287885163
18: 205697230343233228174223751303346572685
17: 332825110087675623210196029789634457848
16: 538522340430300790495419781092981030533
15: 871347450517368352816615810882615488381
14: 1409869790947669143312355919750596518914
13: 2281217241465374961280651402858212007295
12: 3691870324120706639440686994833808526209
11: 5972304273877744135569338397692205335040
10: 9663391306290450775010253925250829059713
9: 15635695580168194910579363790217849593217
8: 25299868864580645685589389182743678652930
7: 40934782466626840596168752972961528246147
6: 66233869353085486281758142155705206899077
5: 107168651819712326877926895128666735145224
4: 173402521172797813159685372843710942044301
3: 280571172992510140037611932413038677189525
2: 453973694165307953197296969697410619233826
1: 734544867157818932349080902110449296423351
func call result: 734544867157818932349080902110449296423351
There are 3 parts, respectively generated by on-stack calculation, on-heap calculation and a non-recursive iterative function that returns the item in the sequence at the specific position.