如何在java中获取大数字的剩余部分

时间:2014-08-14 08:44:24

标签: java

有没有解决这个问题的方法?为什么它返回541而不是3。

public class Test {
    public static void main(String[] args) {
        double a = Math.pow(3, 561);

        // it returns 541 instead of 3
        System.out.println(a % 561);
    }
}

5 个答案:

答案 0 :(得分:11)

根据Fermat's little theorem

Math.pow(a, p) % p == a % p

所以:

Math.pow(3, 561) % 561 = 3 % 561 = 3

因此,您无需进行繁重的计算。只是数学。

答案 1 :(得分:6)

double实际上并不像整数一样。 Java的真正整数类型是java.math.BigInteger

public static void main(String[] args) {
    BigInteger a = new BigInteger("3").pow(561);
    System.out.println(a.mod(new BigInteger("561")));
}

答案 2 :(得分:6)

BigInteger类有一个专门的方法:

import java.math.BigInteger;

public class BigModPow
{
    public static void main(String[] args)
    {
        BigInteger b = new BigInteger("3");
        BigInteger e = new BigInteger("561");
        BigInteger m = new BigInteger("560");
        BigInteger result = b.modPow(e, m);
        System.out.println(result);
    }
}

(编辑:我将模数改为与指数不同的值,以表明计算了一个非平凡的结果 - 尽管561不是素数)

答案 3 :(得分:3)

如果你想计算像 Math.pow(a, b) % m minmal (非零)精度损失,请使用模幂运算公式:
Math.pow(a, b) % m = Math.pow(a, b-1) % m * a
Java递归实现将是:

private int modExp(int a, int b, int m) {
    if (b == 0) return 1;
    if (b == 1) return a % m;
    return (a * modExp(a, b-1, m)) % m;
}

如果a*(m-1)对于int来说太大,则仍然容易出现溢出。另一种选择是BigInteger#modPow使用等效算法。

答案 4 :(得分:3)

由于双精度问题,double无法获得正确的结果。使用BigDecimal

 BigDecimal bigDecimal=new BigDecimal("3").pow(561);
 BigDecimal[] bigDecimal1=bigDecimal.divideAndRemainder(new BigDecimal("561"));
 System.out.println(bigDecimal1[1]);

divideAndRemainder()返回一个双元素数组,其中包含除以积分值的结果,后跟余数。剩余是您正在寻找的部分。

Out put:

3