晚上好。 我已经写了代码计算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的情况下修复?
答案 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
。它在幕后工作以隐藏这个问题。