通过modulo m实现的斐波纳契数给出了负余数除法

时间:2017-03-09 22:08:18

标签: java algorithm

晚上好。 我已经写了代码计算Fibonacchi数字余数的数字n乘以模数m,但结果是在n = 100000之后给出了负余数,之后一切都很好。在使用Long之前,我使用了BigInteger:但是,具有这种变量类型的代码非常慢。我也使用Q-matrices和取幂进行平方。 这是代码:

import java.util.Scanner;

class Main {

private void bigfib(){

    Scanner sc = new Scanner(System.in);
    long  n = sc.nextLong();
    long m = sc.nextLong();

    long [][] a = new long[][]{{1,1},{1,0}};
    System.out.println(pow(a,n)[0][1]%m);

}

private long[][] mult(long[][] m1, long[][] m2) {

    long a11 = m1[0][0]*m2[0][0] + m1[0][1]*m2[1][0];
    long a12 = m1[0][0]*m2[0][1] + m1[0][1]*m2[1][1];
    long a21 = m1[1][0]*m2[0][0] + m1[1][1]*m2[1][0];
    long a22 = m1[1][0]*m2[0][1] + m1[1][1]*m2[1][1];

    long[][] mResult = new long[][]{{a11,a12},{a21,a22}};

    return mResult;

}

private long [][] pow(long a[][], long p) {

    long[][] result;

    if (p==1)
        return a;

    if (p==2)
        return mult(a,a);

    if (p%2==1){
        return mult(a,pow(a,p-1));
    }
    else{
        result = pow(a,p/2);
        return mult(result,result);
    }

}


public static void main(String[] args) {

    new Main().bigfib();

}

}

有人可以告诉我,为什么剩余人员开始变得消极,如何在没有BigItegers的情况下修复?

1 个答案:

答案 0 :(得分:2)

根据您所描述的问题判断(我不点击粘贴链接),看起来您将要了解数字在内存中的表示方式。

如果您使用int,则以32位表示。第一位表示是正还是负,而剩下的31表示数字的大小。

所以这引入了这个有趣的现象:

    0111 1111 1111 1111 =  2,147,483,647
(+) 0000 0000 0000 0001 =              1
-----------------------   --------------
    1000 0000 0000 0000 = -2,147,483,648

要解决您的问题,您应该考虑使用BigInteger。它在幕后工作以隐藏这个问题。