【问题标题】:Fibonacci numbers 1 kk iteration斐波那契数 1 kk 迭代
【发布时间】:2016-02-19 06:35:10
【问题描述】:

我有一个计算斐波那契数的函数

function fib(n) {
  var a = 1,
    b = 1;
  for (var i = 3; i <= n; i++) {
    var c = a + b;
    a = b;
    b = c;
  }
  return b;
}

alert( fib(3) ); // 2
alert( fib(7) ); // 13
alert( fib(77) ); // 5527939700884757

但是使用n &gt; 10000 我得到Infiniti 声明。

如何在 JavaScript 中计算 (n &gt; 1kk) 上的斐波那契数?

【问题讨论】:

  • 使用大库应该是可能的。
  • 是的,this 问题的答案有一些,如果你用谷歌搜索“javascript 无限精度算术”之类的东西,就会有很多。

标签: javascript numbers fibonacci infinity bignum


【解决方案1】:

JavaScript 中的最大整数是 2^53。斐波那契数列的第 1000 个成员在 ~4.35*10^208 处大大超过了这个限制,因此您需要使用大数字库来计算这么高的数字。这是一个使用big.js 轻松解决此问题的示例。

function fib(n) {
    var a = new Big(1),
        b = new Big(1);
    for (var i = 3; i <= n; i++) {
        var c = a.plus(b);
        a = b;
        b = c;
    }
    return b;
}

alert(fib(3)); // 2
alert(fib(7)); // 13
alert(fib(77)); // 5527939700884757
alert(fib(1000)); // 4.346655768...e+208

【讨论】:

    【解决方案2】:

    您需要一个大整数库。要么自己滚动一个(没那么复杂),要么使用网上流传的 js-bigint 库(让我在这里添加一个无耻的self-plug)。

    但是对于 lareg 斐波那契数,您应该使用不同的算法并通过矩阵求幂来完成。如果你使用我的 bigint-library,你可以使用下面的脚本

    function smallfibonacci(n) {
        var i = 1,
            j = 0,
            k, l;
        for (k = 1; k <= n; k++) {
            l = i + j;
            i = j;
            j = l;
        }
        return j;
    }
    
    function fibonacci(n) {
        var i = n - 1,
            r;
        var a, b, c, d, t, t1, t2, t3;
        var e;
    
        if (n <= 76) {
            return smallfibonacci(n).toBigint();
        }
    
        a = new Bigint(1);
        b = new Bigint(0);
        c = new Bigint(0);
        d = new Bigint(1);
    
        while (i > 0) {
            if (i & 0x1) {
                //t = d*(a + b) + c*b;
                t1 = c.mul(b);
                t2 = a.add(b);
                t3 = d.mul(t2);
                t = t3.add(t1);
    
                //a = d*b + c*a;
                t1 = d.mul(b);
                t2 = c.mul(a);
                a = t1.add(t2);
                //b = t;
                b = t.copy();
            }
            //t = d*(2*c + d);
            t1 = c.lShift(1);
            t2 = t1.add(d);
            t = d.mul(t2);
    
            //c = c*c + d*d;
            t1 = c.sqr();
            t2 = d.sqr();
            c = t1.add(t2);
            //d = t;
            d = t.copy();
            i >>>= 1;
        }
        r = a.add(b);
        return r;
    }
    
    fibonacci(10000).toString();
    

    到字符串的转换仍未优化,需要大部分运行时间。在这台中等功率的机器上计算(但不是打印!)F(1,000,000) 大约需要 24 秒。

    【讨论】:

      猜你喜欢
      • 2013-02-09
      • 2018-08-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多