Javascript中大数的斐波那契

Javascript中大数的斐波那契,javascript,fibonacci,Javascript,Fibonacci,我有以下代码: function fib(n) { let first=BigInt(0); let snd=BigInt(1); let currentNumber; let countMax=Math.abs(n)+1; let counter=2; if(n==0){ return first; } else if (n==1||n==-1){ return snd; } while(counter<countMax)

我有以下代码:

function fib(n) {

  let first=BigInt(0);
  let snd=BigInt(1);
  let currentNumber;
  let countMax=Math.abs(n)+1;
  let counter=2;
  if(n==0){

    return first;
  } 
  else if (n==1||n==-1){

    return snd;
  }
  while(counter<countMax)
  {
        currentNumber=first+snd;
        first=snd;
        snd=currentNumber;
        counter++;
  }
  if((n<0) && (n % 2 ==0))
  {
    return -currentNumber;
  }
  return currentNumber;
}
函数fib(n){
设first=BigInt(0);
设snd=BigInt(1);
让我们来看看这个数字;
设countMax=Math.abs(n)+1;
设计数器=2;
如果(n==0){
先返回;
} 
else if(n==1 | | n==1){
返回snd;
}

而(counter如果您只是将上一个值添加到当前值,然后将旧的当前值用作上一个值,则性能会显著提高

函数fib(n){
无功电流=1;
var-previous=0;
而(--n){
var温度=电流;
当前+=以前;
先前=温度;
}
回流;
}
console.log(fib(1));//1
console.log(fib(2));//1
console.log(fib(3));//2
console.log(fib(4));//3

console.log(fib(5));/5
首先,您可以参考下面的答案

Fib(-n)=-Fib(n)

这里的递归实现并不像您提到的那样高效

function fib(n) {
    // This is to handle positive and negative numbers
    var sign = n >= 0 ? 1 : -1;
    n = Math.abs(n);

    // Now the usual Fibonacci function
    if(n < 2)
        return sign*n;
    return sign*(fib(n-1) + fib(n-2));
}
尝试一些测试用例。很容易理解为什么这会更快

现在您知道可以存储已计算的值,您可以修改您的解决方案以使用此方法,而不使用递归,因为对于大数,递归方法将抛出
Uncaught RangeError
。我将此留给您,因为它值得您自己尝试


此解决方案在编程中使用了一个称为动态编程的概念。如果我记得的话,您可以参考它。

(因此是注释,而不是答案),在进行斐波那契运算时,随着
n
的增加,你会一次又一次地计算相同的值。如果是这种情况,你可以存储前50个数字的斐波那契值,然后在计算时使用它。这将节省你每次从头开始重新计算的时间。你需要负数值的斐波那契吗成员数?是的,我也需要Fibonacci数。存储第一个X数可能很好,但它是一个独立的函数,无法存储数字以供将来使用。不幸的是,每次都必须从头开始执行。如果删除
bigint
,会发生什么?它们是一个非常新的功能,而且是新的!=我忘记告诉你了我也试过了。我看到一些文章说使用循环减法更快,但仍然不够快:-)事实上,当我执行fib(100000)时它需要超过12秒,这是一台有限的机器,我开始认为不可能比你输入的代码提高更多的性能。谢谢!@Jose3d我更新了答案,我还包括了一个基准测试,让你自己看看差异。谢谢你的帮助,我现在有足够的信息来改进它。出色的ex刨床,谢谢!
function fib(n) {
    if(n == 0)
        return 0;
    var a = 1;
    var b = 1;
    while(n > 2) {
        b = a + b;
        a = b - a;
    }
    // If n is negative then return negative of fib(n)
    return n < 0 ? -1*b : b;
}
// This object will store already calculated values
// This should be in the global scope or atleast the parent scope
var memo = {};

// We know fib(0) = 0, fib(1) = 1, so store it
memo[0] = 0;
memo[1] = 1;

function fib(n) {
    var sign = n >= 0 ? 1 : -1;
    n = Math.abs(n);

    // If we already calculated the value, just use the same
    if(memo[n] !== undefined)
        return sign*memo[n];

    // Else we will calculate it and store it and also return it
    return sign*(memo[n] = fib(n-1) + fib(n-2));
}

// This will calculate fib(2), fib(3), fib(4) and fib(5). 
// Why it does not calculate fib(0) and fib(1) ? 
// Because it's already calculated, goto line 1 of this code snippet
console.log(fib(5)); // 5

// This will not calculate anything 
// Because fib(-5) is -fib(5) and we already calculated fib(5)
console.log(fib(-5)); // -5

// This will also not calculate anything
// Because we already calculated fib(4) while calculating fib(5)
console.log(fib(4)); // 3

// This will calculate only fib(6) and fib(7)
console.log(fib(7)); // 13