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.