A recursive function of fibonacci in bash

advertisements

This question already has an answer here:

  • recursive fibonacci linux bash script 4 answers

I was perusing the sight for some help with my code and came across a thread from about 4 months ago, however the user's final revision doesn't work when posted into bash, and produces some strange results. Here is my version, which also produces some strange results:

#!/bin/bash
fib()
{
ind=$1

if (( ind <= 0 ))
 then echo 0
elif (( ind = 1 ))
 then echo 1
else
  echo $(( $(fib $((ind - 1)) ) + $(fib $((ind - 2)) ) ))
fi
}
echo fibbonacci sequence number $1 is $(fib $1)

so this block of code will end up always outputting 1. ./fib.sh 5 outputs fibbonacci sequence number 5 is 1

so I tried to write the code a little closer to what the previous asker had,

#!/bin/bash

fib()
 {
  ind=$1

if (( ind <= 0 ))
 then echo 1
else
  echo $(( $(fib $((ind - 1)) ) + $(fib $((ind - 2)) ) ))
fi
 }
 echo fibbonacci sequence number $1 is $(fib $1)

While I don't understand the logic here, it actually starts to output fibonacci numbers, but now I get a slightly different problem; ./fib.sh 3 outputs: fibbonacci sequence number 3 is 5 ./fib.sh 5 outputs : fibbonacci sequence number 5 is 13 Well we know that the 3rd fibonacci number is 1, and the 5th is 3 so what gives? The code seems to skip ahead several fibonacci numbers, and I can't figure out what is logically wrong with my code.


Usually when writing Fibonacci sequence logic you have to special-case the first two numbers. That's what the first user has done: special-casing 0 and 1.

You've removed one instance of special-casing and shifted everything by one index, which explains one shift. The other is easy: the code is zero-indexed. That's why everything is "off by two".

What's wrong with the original code? This line:

elif ((ind = 1))

sets ind to 1. Otherwise it's fine.

A simple fix to your code is to replace this line:

if (( ind <= 0 ))

with

if (( ind <= 2 ))

and off you go. That gives you the one-indexed behavior you'd expect:

[email protected] ~/foo> for i in `seq 1 10`; do ./foo.sh $i; done
fibbonacci sequence number 1 is 1
fibbonacci sequence number 2 is 1
fibbonacci sequence number 3 is 2
fibbonacci sequence number 4 is 3
fibbonacci sequence number 5 is 5
fibbonacci sequence number 6 is 8
fibbonacci sequence number 7 is 13
fibbonacci sequence number 8 is 21
fibbonacci sequence number 9 is 34
fibbonacci sequence number 10 is 55