Fibonacci with ADA and others (Part 3/3)

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, 

 1 with ariane.numerics.biginteger;

 2 use ariane.numerics;

 3 with ada.text_io;

 4 use ada.text_io;

 5 with ada.strings.Fixed;

 6 use ada.Strings.fixed;

 7 use ada.Strings;

 8 

 9 procedure test_numerics_biginteger is

10 

11   package bigint is new biginteger(length_t=>integer);

12   use type bigint.object;  -- this only works for operators

13 

14   function fibonacci_onstack(a, b : bigint.object; n : integer)

15                              return bigint.object is

16     -- initialize both a and b to 1

17     c : bigint.object := a + b;

18   begin

19     if n > 1 then

20       declare

21         r : bigint.object := fibonacci_onstack(b, c, n - 1);

22       begin

23         return r;

24       end;

25     else

26       return c;

27     end if;

28   end fibonacci_onstack;

29 

30   -- produces and displays fibonacci sequence to the n-th item

31   -- it is recursively working on stack

32   procedure fibonacci_onstack(a, b : bigint.object; n : integer) is

33     c : bigint.object := a + b;

34   begin

35     put(trim(integer'image(n), both)); put(": ");

36     put_line(bigint.tostring(c));

37     if n > 1 then

38       fibonacci_onstack(b, c, n - 1);

39     end if;

40   end fibonacci_onstack;

41 

42   procedure fibonacci_onheap(n : integer) is

43     pa : bigint.objectptr := new bigint.object(1);

44     pb : bigint.objectptr := new bigint.object(1);

45     pc : bigint.objectptr;

46     a : bigint.object := bigint.create((1=>1));

47   begin

48     pa.all := a;

49     pb.all := a;

50 

51     for i in 1 .. n loop

52       pc := bigint.create(pa.all + pb.all);

53       put(trim(integer'image(n-i+1), both)); put(": ");

54       put_line(bigint.tostring(pc.all));

55       bigint.free(pa);

56       pa := pb;

57       pb := pc;

58     end loop;

59 

60     bigint.free(pa);

61     bigint.free(pb);

62 

63   end fibonacci_onheap;

64 

65   -- variable declarations

66 

67   a : bigint.object := bigint.create((1=>1));

68   b : bigint.object := a;

69 

70 begin

71 

72   fibonacci_onstack(a, b, 200);

73 

74   fibonacci_onheap(200);

75 

76   declare

77     -- note that ADA compiler can differentiate the function call from the

78     -- procedure call even if their signatures are exactly the same from most

79     -- other programming languages' perspective

80     r : bigint.object := fibonacci_onstack(a, b, 200);

81   begin

82     put("func call result: ");

83     put_line(bigint.tostring(r));

84   end;

85 

86 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.

 

你可能感兴趣的:(fibonacci)