java - 在 java 上通过模 m 实现的斐波那契数给出除法的负余数

标签 java algorithm

<分区>

晚上好。 我已经编写了代码来计算斐波那契数的余数 n 和模 m,但结果是在 n=100000 之后给我负余数,在此之前一切都很好。在使用 Long 之前,我使用 BigInteger 代替:但是,具有这种变量类型的代码非常慢。我还使用 Q 矩阵和平方求幂。 这是代码:

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 如何解决这个问题?

最佳答案

从您描述的问题来看(我没有点击 pastebin 链接),您似乎即将了解数字在内存中的表示方式。

如果您使用的是 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。它在幕后工作以向您隐藏此问题。

关于java - 在 java 上通过模 m 实现的斐波那契数给出除法的负余数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42706403/

相关文章:

PHP类别反向遍历算法

java - 转换为流

java - 如何以编程方式设置 imageView 的高度?

java - 无法让机器人类右键单击

c++ - 将 n 个元素插入 vector 的空间复杂度

algorithm - n 个字符串的最长公共(public)前缀

java - 可以吗?如何将商业库上传到 Maven Central?

java - log4j:WARN 请正确初始化 log4j 系统

algorithm - 如何将三角形的二维网格转换为四边形?

Java 数组算法,将 shuffle 类型从 "in-shuffle"交换到 "out-shuffle"时出错