Fibonacci number: what changed
Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.
Title: Fibonacci number
| Old | New | Line | |
|---|---|---|---|
| 1 | + | The Fibonacci Sequence is the series of numbers: | |
| 2 | + | ||
| 3 | + | ``` pascal | |
| 4 | + | 0, 1, 1, 2, 3, 5, 8, 13, 21, … | |
| 5 | + | ``` | |
| 6 | + | ||
| 7 | + | The idea is to add the two last numbers in order to produce the next value. | |
| 8 | + | ||
| 9 | + | ## generation | |
| 10 | + | ||
| 11 | + | The following implementations show the *principle* of how to calculate Fibonacci numbers. They lack of input checks. Depending on your preferences you might either want to generate a [[runtime error|run-time error]] (e. g. by [[$rangeChecks|{$rangeChecks on}]] or utilizing [`system.runError`](https://www.freepascal.org/docs-html/rtl/system=/runerror.html)), [[Raise|raise]] an [[Exceptions|exception]], or simply return a bogus value indicating something went wrong. | |
| 12 | + | ||
| 13 | + | ### recursive implementation | |
| 14 | + | ||
| 15 | + | ``` pascal | |
| 16 | + | type | |
| 17 | + | /// domain for Fibonacci function | |
| 18 | + | /// where result is within nativeUInt | |
| 19 | + | // You can not name it fibonacciDomain, | |
| 20 | + | // since the Fibonacci function itself | |
| 21 | + | // is defined for all whole numbers | |
| 22 | + | // but the result beyond F(n) exceeds high(nativeUInt). | |
| 23 | + | fibonacciLeftInverseRange = | |
| 24 | + | {$ifdef CPU64} 0..93 {$else} 0..47 {$endif}; | |
| 25 | + | ||
| 26 | + | {** | |
| 27 | + | implements Fibonacci sequence recursively | |
| 28 | + | ||
| 29 | + | \param n the index of the Fibonacci number to retrieve | |
| 30 | + | \returns the Fibonacci value at n | |
| 31 | + | } | |
| 32 | + | function fibonacci(const n: fibonacciLeftInverseRange): nativeUInt; | |
| 33 | + | begin | |
| 34 | + | // optimization: then part gets executed most of the time | |
| 35 | + | if n > 1 then | |
| 36 | + | begin | |
| 37 | + | fibonacci := fibonacci(n - 2) + fibonacci(n - 1); | |
| 38 | + | end | |
| 39 | + | else | |
| 40 | + | begin | |
| 41 | + | // since the domain is restricted to non-negative integers | |
| 42 | + | // we can bluntly assign the result to n | |
| 43 | + | fibonacci := n; | |
| 44 | + | end; | |
| 45 | + | end; | |
| 46 | + | ``` | |
| 47 | + | ||
| 48 | + | ### iterative implementation | |
| 49 | + | ||
| 50 | + | This one is preferable for its [[runtime|run-time]] behavior. | |
| 51 | + | ||
| 52 | + | ``` pascal | |
| 53 | + | {** | |
| 54 | + | implements Fibonacci sequence iteratively | |
| 55 | + | ||
| 56 | + | \param n the index of the Fibonacci number to calculate | |
| 57 | + | \returns the Fibonacci value at n | |
| 58 | + | } | |
| 59 | + | function fibonacci(const n: fibonacciLeftInverseRange): nativeUInt; | |
| 60 | + | type | |
| 61 | + | /// more meaningful identifiers than simple integers | |
| 62 | + | relativePosition = (previous, current, next); | |
| 63 | + | var | |
| 64 | + | /// temporary iterator variable | |
| 65 | + | i: longword; | |
| 66 | + | /// holds preceding fibonacci values | |
| 67 | + | f: array[relativePosition] of nativeUInt; | |
| 68 | + | begin | |
| 69 | + | f[previous] := 0; | |
| 70 | + | f[current] := 1; | |
| 71 | + | ||
| 72 | + | // note, in Pascal for-loop-limits are inclusive | |
| 73 | + | for i := 1 to n do | |
| 74 | + | begin | |
| 75 | + | f[next] := f[previous] + f[current]; | |
| 76 | + | f[previous] := f[current]; | |
| 77 | + | f[current] := f[next]; | |
| 78 | + | end; | |
| 79 | + | ||
| 80 | + | // assign to previous, bc f[current] = f[next] for next iteration | |
| 81 | + | fibonacci := f[previous]; | |
| 82 | + | end; | |
| 83 | + | ``` | |
| 84 | + | ||
| 85 | + | ## lookup | |
| 86 | + | ||
| 87 | + | While calculating the Fibonacci number every time it is needed requires almost no space, it takes a split second of time. [[Application|Applications]] heavily relying on Fibonacci numbers definitely want to use a lookup table instead. And yet in general, do not calculate what is already a known fact. Since the Fibonacci sequence doesn’t change, actually calculating it is a textbook demonstration but not intended for production use. | |
| 88 | + | ||
| 89 | + | Nevertheless an actual implementation is omitted here, since everyone wants to have it differently, a different flavor. | |
| 90 | + | ||
| 91 | + | ## see also | |
| 92 | + | ||
| 93 | + | - [Fibonacci numbers in the on-line encyclopedia of integer sequences](https://oeis.org/A000045) | |
| 94 | + | - [Some assembly routine which uses the C calling convention that calculates the nth Fibonacci number](https://freepascal.org/docs-html/current/prog/progsu150.html) | |
| 95 | + | - [Fibonacci sequence § “Pascal” on RosettaCode.org](https://rosettacode.org/wiki/Fibonacci_sequence#Pascal) | |
| 96 | + | - [[gmp|GNU multiple precision arithmetic library]]’s functions [`mpz_fib_ui` and `mpz_fib2_ui`](https://gmplib.org/manual/Fibonacci-Numbers-Algorithm.html#Fibonacci-Numbers-Algorithm) | |
| 97 | + | - [[Lucas number]], a similar series with different initial values | |
| 98 | + | - [[Solution 3|Tao Yue Solution to Fibonacci Sequence Problem]] | |
| 99 | + | ||
| 100 | + | --- | |
| 101 | + | *From the Free Pascal wiki, page "Fibonacci number", as it stood on 2019-10-23 after a change by Kai Burghardt, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* |
