javascript - 如何找到一个非常大的整数的余数

时间:2014-04-09 07:04:20

标签: javascript

我通过这样做找出 n 数量的斐波纳契序列:

function add(a, b) {
while (a.length < b.length) a.unshift(0);
while (a.length > b.length) b.unshift(0);
var carry = 0, sum = []
for (var i = a.length - 1; i >= 0; i--) {
    var s = a[i] + b[i] + carry;
    if (s >= 10) {
        s = s - 10;
        carry = 1;
    } else {
        carry = 0;
    }
    sum.unshift(s);
}
if (carry)
    sum.unshift(carry);
return sum;
}
function fib(n) {
var f1 = [0];
var f2 = [1];

while (n--) {
    var f3 = add(f1, f2)
    f1 = f2;
    f2 = f3;
}
return f1.join("");
}

说,我想找到1995年斐波那契数除以8时的余数。这样做,

fib(1995) % 8
然而,

返回NaN。这是fiddle,输出为console.log

那么如何找到1995年斐波那契数的剩余部分除以8?

3 个答案:

答案 0 :(得分:3)

您所描述的数字理论的一个非常特殊的应用称为Pisano period

  

在数论中,第n个Pisano时期,写成π(n),是Fibonacci数的序列,模n重复的时期。例如,模3的Fibonacci数是0,1,1,2,0,2,2,1,0,1,1,2,0,2,2,1等,前八个数重复,所以π(3)= 8。

n = 8的Pisano期间是12,所以你正在寻找重复序列的(1995 % 12)'元素,所以:

0 1 1 2 3 5 0 5 5 2 7 1
      ^

更新

正如评论中所提到的,每增加一对,您都可以应用模数来保持数字的可管理性:

function fib(n, mod)
{
    if (n == 0) {
        return 0;
    } else if (n <= 2) {
        return 1;
    }

    var current = 1,
    tmp,
    prev = 1;

    while (n > 2) {
        tmp = current;

        current = (current + prev) % mod;
        prev = tmp;

        --n;
    }

    return current;
}

fib(1995, 8); // 2

答案 1 :(得分:1)

我在尝试验证IBAN号码时遇到了这个问题(欧洲银行帐户标准)。它利用一个控制号来避免错误输入账户的交易(模数97的结果总是应该是1)。

我找到了一个要点(IBAN javascript validator gist),它也能够满足你的需要。这是有用的部分(注意:divident参数必须是STRING ):

modulo = function (divident, divisor) {
    var cDivident = '';
    var cRest = '';

    for (var i in divident ) {
         var cChar = divident[i];
         var cOperator = cRest + '' + cDivident + '' + cChar;

         if ( cOperator < parseInt(divisor) ) {
             cDivident += '' + cChar;
         } else {
             cRest = cOperator % divisor;
             if ( cRest == 0 ) {
                cRest = '';
             }
             cDivident = '';
        }

    }
    cRest += '' + cDivident;
    if (cRest == '') {
        cRest = 0;
    }
    return cRest;
}; 

基本上,它将大数字砍成较小的数量,可以通过javascript处理。 这是一个工作小提琴:

jsFiddle example of modulo with big integers in javascript

答案 2 :(得分:0)

var cache = {};
var result = 0;
function fib_mod(number, mod) {
    if( cache[number] ) return cache[number];

    if( number < 3 ) result = 1 % mod; // 1st is 1, 2nd is 1 too
    else result = (fib_mod(number-2, mod) + fib_mod(number-1, mod)) % mod;

    cache[number] = result;

    return result;
}

fib_mod(1995,8); // output is 2

JsFiddle在这里:http://jsfiddle.net/y5B7q/