# Fibonacci numbers (PIR)

Other implementations: bc | C | C Plus Plus templates | dc | E | Erlang | FORTRAN | Haskell | Icon | Java | JavaScript | Lisp | Lua | occam | Oz | Pascal | PIR | PostScript | Prolog | Python | Ruby | Scala | Scheme | Sed | sh | sh, iterative | Smalltalk | T-SQL | Visual Basic .NET

The Fibonacci numbers are the integer sequence 0, 1, 1, 2, 3, 5, 8, 13, 21, ..., in which each item is formed by adding the previous two. The sequence can be defined recursively by

$F(n) = \begin{cases} 0 & n = 0 \\ 1 & n = 1 \\ F(n-1)+F(n-2) & n > 1 \\ \end{cases} .$

Fibonacci number programs that implement this definition directly are often used as introductory examples of recursion. However, many other algorithms for calculating (or making use of) Fibonacci numbers also exist.

In this article we show two ways of calculating fibonacci numbers in PIR.

<<fib.pir>>=

fib

fastfib

test



##  Recursive

This is a very simple recursive implementation. This will become slow on big numbers, because the numbers are recalculated for each recursion.

The PIR language gives us some help not available in regular assembly languages. The .param and .local macros creates named local registers, so that we don't need to care about register allocation, lifetime and other such details.

<<fib>>=
.sub fib
.param int n
.local int f1
.local int f2

if n <= 1 goto END

n = n - 1
f1 = fib(n)
n = n - 1
f2 = fib(n)

n = f1 + f2

END:
.return (n)
.end


##  Iterative

This is a faster, but also somewhat more complicated way to calculate fibonacci numbers. To avoid recalculation, the numbers are stored in local registers, for later reuse.

<<fastfib>>=
.sub ffib
.param int n
.local int f1
.local int f2
.local int tmp

if n <= 1 goto END

f1 = 0
f2 = 1

n = n - 1
LOOP:
tmp = f2
f2 = f1 + f2
f1 = tmp

n = n - 1
if n > 0 goto LOOP

n = f1
if f1 > f2 goto END
n = f2

END:
.return (n)
.end


##  Test

If we run this test code, we can see that the iterative method is significantly faster then the recursive.

<<test>>=
.sub main :main
.local int f
.local int n

n = 0

FIBLOOP:
f = fib(n)

print n
print ": "
print f
print "\n"

n = n + 1

if n > 30 goto FIBEND

goto FIBLOOP

FIBEND:
n = 0

FFIBLOOP:
f = ffib(n)

print n
print ": "
print f
print "\n"

n = n + 1

if n > 30 goto END

goto FFIBLOOP

END:
.end


hijacker
hijacker
hijacker
hijacker
{"extraction_info": {"found_math": true, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 0, "mathjax_display_tex": 0, "mathjax_asciimath": 1, "img_math": 1, "codecogs_latex": 0, "wp_latex": 0, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0, "katex": 0, "math-container": 0, "wp-katex-eq": 0, "align": 0, "equation": 0, "x-ck12": 0, "texerror": 0, "math_score": 0.2812347412109375, "perplexity": 5361.056232217171}, "config": {"markdown_headings": true, "markdown_code": true, "boilerplate_config": {"ratio_threshold": 0.18, "absolute_threshold": 10, "end_threshold": 15, "enable": true}, "remove_buttons": true, "remove_image_figures": true, "remove_link_clusters": true, "table_config": {"min_rows": 2, "min_cols": 3, "format": "plain"}, "remove_chinese": true, "remove_edit_buttons": true, "extract_latex": true}, "warc_path": "s3://commoncrawl/crawl-data/CC-MAIN-2015-35/segments/1440645176794.50/warc/CC-MAIN-20150827031256-00207-ip-10-171-96-226.ec2.internal.warc.gz"}