Generating Fibonacci Sequence

Generating Fibonacci Sequence
var x = 0;
var y = 1;
var z;

fib[0] = 0;
fib[1] = 1;

for (i = 2; i <= 10; i++) {
  alert(x + y);
  fib[i] = x + y;
  x = y;
  z = y;
}

I'm trying to get to generate a simple Fibonacci Sequence but there no output.

Can anybody let me know what's wrong?

50 Answers

You have never declared fib to be an array. Use var fib = []; to solve this.

Also, you're never modifying the y variable, neither using it.

The code below makes more sense, plus, it doesn't create unused variables:

var i;
var fib = [0, 1]; // Initialize array!

for (i = 2; i <= 10; i++) {
  // Next fibonacci number = previous + one before previous
  // Translated to JavaScript:
  fib[i] = fib[i - 2] + fib[i - 1];
  console.log(fib[i]);
}
2

According to the Interview Cake question, the sequence goes 0,1,1,2,3,5,8,13,21. If this is the case, this solution works and is recursive without the use of arrays.

function fibonacci(n) {
   return n < 1 ? 0
        : n <= 2 ? 1
        : fibonacci(n - 1) + fibonacci(n - 2)
}

console.log(fibonacci(4))

Think of it like this.

   fibonacci(4)   .--------> 2 + 1 = 3
      |          /               |
      '--> fibonacci(3) + fibonacci(2)
            |    ^           
            |    '----------- 2 = 1 + 1 <----------.
1st step -> |                     ^                |
            |                     |                |
            '---->  fibonacci(2) -' + fibonacci(1)-'

Take note, this solution is not very efficient though.

10

Yet another answer would be to use es6 generator functions.

function* fib() {
  var current = a = b = 1;

  yield 1;

  while (true) {
    current = b;

    yield current;

    b = a + b;
    a = current;
  }
}

sequence = fib();
sequence.next(); // 1
sequence.next(); // 1
sequence.next(); // 2
// ...
1

Here's a simple function to iterate the Fibonacci sequence into an array using arguments in the for function more than the body of the loop:

fib = function(numMax){
    for(var fibArray = [0,1], i=0,j=1,k=0; k<numMax;i=j,j=x,k++ ){
        x=i+j;
        fibArray.push(x);
    }
    console.log(fibArray);
}

fib(10)

[ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 ]

2

You should've declared the fib variable to be an array in the first place (such as var fib = [] or var fib = new Array()) and I think you're a bit confused about the algorithm.
If you use an array to store the fibonacci sequence, you do not need the other auxiliar variables (x,y,z) :

var fib = [0, 1];
for(var i=fib.length; i<10; i++) {
    fib[i] = fib[i-2] + fib[i-1];
}
console.log(fib); 

Click for the demo

You should consider the recursive method too (note that this is an optimised version) :

function fib(n, undefined){
    if(fib.cache[n] === undefined){
        fib.cache[n] = fib(n-1) + fib(n-2);
    }

    return fib.cache[n];
}
fib.cache = [0, 1, 1];

and then, after you call the fibonacci function, you have all the sequence in the fib.cache field :

fib(1000);
console.log(fib.cache);

The golden ration "phi" ^ n / sqrt(5) is asymptotic to the fibonacci of n, if we round that value up, we indeed get the fibonacci value.

function fib(n) {
    let phi = (1 + Math.sqrt(5))/2;
    let asymp = Math.pow(phi, n) / Math.sqrt(5);

    return Math.round(asymp);
}

fib(1000); // 4.346655768693734e+208 in just a few milliseconds

This runs faster on large numbers compared to the recursion based solutions.

4

You're not assigning a value to z, so what do you expect y=z; to do? Likewise you're never actually reading from the array. It looks like you're trying a combination of two different approaches here... try getting rid of the array entirely, and just use:

// Initialization of x and y as before

for (i = 2; i <= 10; i++)
{
    alert(x + y);
    z = x + y;
    x = y;
    y = z;
}

EDIT: The OP changed the code after I'd added this answer. Originally the last line of the loop was y = z; - and that makes sense if you've initialized z as per my code.

If the array is required later, then obviously that needs to be populated still - but otherwise, the code I've given should be fine.

2

Another easy way to achieve this:

function listFibonacci(n) {
  // declare the array starting with the first 2 values of the fibonacci sequence
  // starting at array index 1, and push current index + previous index to the array
  for (var fibonacci = [0, 1], i = 1; i < n; i++) 
    fibonacci.push(fibonacci[i] + fibonacci[i - 1])

  return fibonacci
}

console.log(  listFibonacci(10)  )
3
function fib(n) {
  if (n <= 1) {
    return n;
  } else {
    return fib(n - 1) + fib(n - 2);
  }
}

fib(10); // returns 55
2

fibonacci 1,000 ... 10,000 ... 100,000

Some answers run into issues when trying to calculate large fibonacci numbers. Others are approximating numbers using phi. This answer will show you how to calculate a precise series of large fibonacci numbers without running into limitations set by JavaScript's floating point implementation.

Below, we generate the first 1,000 fibonacci numbers in a few milliseconds. Later, we'll do 100,000!

const { fromInt, toString, add } =
  Bignum

const bigfib = function* (n = 0)
{
  let a = fromInt (0)
  let b = fromInt (1)
  let _
  while (n >= 0) {
    yield toString (a)
    _ = a
    a = b
    b = add (b, _)
    n = n - 1
  }
}

console.time ('bigfib')
const seq = Array.from (bigfib (1000))
console.timeEnd ('bigfib')
// 25 ms

console.log (seq.length)
// 1001

console.log (seq)
// [ 0, 1, 1, 2, 3, ... 995 more elements ]

Let's see the 1,000th fibonacci number

console.log (seq [1000])
// 43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875

10,000

This solution scales quite nicely. We can calculate the first 10,000 fibonacci numbers in under 2 seconds. At this point in the sequence, the numbers are over 2,000 digits long – way beyond the capacity of JavaScript's floating point numbers. Still, our result includes precise values without making approximations.

console.time ('bigfib')
const seq = Array.from (bigfib (10000))
console.timeEnd ('bigfib')
// 1877 ms

console.log (seq.length)
// 10001

console.log (seq [10000] .length)
// 2090

console.log (seq [10000])
// 3364476487 ... 2070 more digits ... 9947366875

Of course all of that magic takes place in Bignum, which we will share now. To get an intuition for how we will design Bignum, recall how you added big numbers using pen and paper as a child...

  1259601512351095520986368
+   50695640938240596831104
---------------------------
                          ?

You add each column, right to left, and when a column overflows into the double digits, remembering to carry the 1 over to the next column...

                 ... <-001
  1259601512351095520986368
+   50695640938240596831104
---------------------------
                  ... <-472

Above, we can see that if we had two 10-digit numbers, it would take approximately 30 simple additions (3 per column) to compute the answer. This is how we will design Bignum to work

const Bignum =
  { fromInt: (n = 0) =>
      n < 10
        ? [ n ]
        : [ n % 10, ...Bignum.fromInt (n / 10 >> 0) ]
        
  , fromString: (s = "0") =>
      Array.from (s, Number) .reverse ()
      
  , toString: (b) =>
      Array.from (b) .reverse () .join ('')
      
  , add: (b1, b2) =>
    {
      const len = Math.max (b1.length, b2.length)
      let answer = []
      let carry = 0
      for (let i = 0; i < len; i = i + 1) {
        const x = b1[i] || 0
        const y = b2[i] || 0
        const sum = x + y + carry
        answer.push (sum % 10)
        carry = sum / 10 >> 0
      }
      if (carry > 0) answer.push (carry)
      return answer
    }
  }

We'll run a quick test to verify our example above

const x =
  fromString ('1259601512351095520986368')

const y =
  fromString ('50695640938240596831104')

console.log (toString (add (x,y)))
// 1310297153289336117817472

And now a complete program demonstration. Expand it to calculate the precise 10,000th fibonacci number in your own browser! Note, the result is the same as the answer provided by wolfram alpha

const Bignum =
  { fromInt: (n = 0) =>
      n < 10
        ? [ n ]
        : [ n % 10, ...Bignum.fromInt (n / 10 >> 0) ]
        
  , fromString: (s = "0") =>
      Array.from (s, Number) .reverse ()
      
  , toString: (b) =>
      Array.from (b) .reverse () .join ('')
      
  , add: (b1, b2) =>
    {
      const len = Math.max (b1.length, b2.length)
      let answer = []
      let carry = 0
      for (let i = 0; i < len; i = i + 1) {
        const x = b1[i] || 0
        const y = b2[i] || 0
        const sum = x + y + carry
        answer.push (sum % 10)
        carry = sum / 10 >> 0
      }
      if (carry > 0) answer.push (carry)
      return answer
    }
  }
  
const { fromInt, toString, add } =
  Bignum

const bigfib = function* (n = 0)
{
  let a = fromInt (0)
  let b = fromInt (1)
  let _
  while (n >= 0) {
    yield toString (a)
    _ = a
    a = b
    b = add (b, _)
    n = n - 1
  }
}

console.time ('bigfib')
const seq = Array.from (bigfib (10000))
console.timeEnd ('bigfib')
// 1877 ms
   
console.log (seq.length)
// 10001

console.log (seq [10000] .length)
// 2090

console.log (seq [10000])
// 3364476487 ... 2070 more digits ... 9947366875

100,000

I was just curious how far this little script could go. It seems like the only limitation is just time and memory. Below, we calculate the first 100,000 fibonacci numbers without approximation. Numbers at this point in the sequence are over 20,000 digits long, wow! It takes 3.18 minutes to complete but the result still matches the answer from wolfram alpha

console.time ('bigfib')
const seq = Array.from (bigfib (100000))
console.timeEnd ('bigfib')
// 191078 ms

console.log (seq .length)
// 100001

console.log (seq [100000] .length)
// 20899

console.log (seq [100000])
// 2597406934 ... 20879 more digits ... 3428746875

BigInt

JavaScript now has native support for BigInt. This allows for calculating huge integers very quickly -

function* fib (n)
{ let a = 0n
  let b = 1n
  let _
  while (n >= 0) {
    yield a.toString()
    _ = a
    a = b
    b = b + _
    n = n - 1
  }
}

console.time("fib(1000)")
const result = Array.from(fib(1000))
console.timeEnd("fib(1000)")
document.body.textContent = JSON.stringify(result, null, 2)
body {
    font-family: monospace;
    white-space: pre;
}

I like the fact that there are so many ways to create a fibonacci sequence in JS. I will try to reproduce a few of them. The goal is to output a sequence to console (like {n: 6, fiboNum: 8})

Good ol' closure

// The IIFE form is purposefully omitted. See below.

const fiboGenClosure = () => {
  let [a, b] = [0, 1];
  let n = 0;
  return (fiboNum = a) => {
    [a, b] = [b, a + b];
    return {
      n: n++,
      fiboNum: fiboNum
    };
  };
}

// Gets the sequence until given nth number. Always returns a new copy of the main function, so it is possible to generate multiple independent sequences.

const generateFiboClosure = n => {
  const newSequence = fiboGenClosure();
  for (let i = 0; i <= n; i++) {
    console.log(newSequence());
  }
}

generateFiboClosure(21);
Maya Lin-Takahashi
Author

Maya Lin-Takahashi

Maya is a hardware enthusiast who tests and reviews smart home devices, smartphones, wearables, and audio gear. She focuses on practical consumer value and build quality.