有没有解决这个问题的方法?为什么它返回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);
}
}
答案 0 :(得分:11)
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