现在的位置: 首页 > 综合 > 正文

Fibonacci with ADA and others (Part 3/3)

2013年12月08日 ⁄ 综合 ⁄ 共 13773字 ⁄ 字号 评论关闭

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.

抱歉!评论已关闭.