Java总是用巨大的数字给我错误的结果
我写了这行代码:Java总是用巨大的数字给我错误的结果,java,numbers,Java,Numbers,我写了这行代码: System.out.println(Math.pow(7, 23) % 143); // 7^23 mod 143 我希望输出是2,但输出是93.0。有人知道我做错了什么吗?数字“overflows”double,这是Math.pow()所期望和返回的。改用biginger: BigInteger.valueOf(7) .pow(23) .mod(BigInteger.valueOf(143)) 或者在单个步骤中,如@Felk所建议的:
System.out.println(Math.pow(7, 23) % 143); // 7^23 mod 143
我希望输出是2
,但输出是93.0
。有人知道我做错了什么吗?数字“overflows”double
,这是Math.pow()
所期望和返回的。改用biginger
:
BigInteger.valueOf(7)
.pow(23)
.mod(BigInteger.valueOf(143))
或者在单个步骤中,如@Felk所建议的:
BigInteger.valueOf(7)
.modPow(BigInteger.valueOf(23), BigInteger.valueOf(143))
Math.pow
的结果是一个double
,它有64位;其中53个是尾数位。这意味着任何大于2^53-1=9007199254740991
的整数都不能精确表示为双精度整数
7^23比2^53-1大(实际上只是比2^64大一点),因此无法精确表示。因此,%
的结果不是您期望的结果
如前所述,使用biginger
。如果中间求幂结果太大而无法保存在变量中,则使用a
System.out.println(powMod(7, 23, 143)); // = 2
// Example from Wikipedia with minor changes
private static int powMod(int base, int exponent, int modulus) {
if (modulus == 1)
return 0;
base %= modulus;
int result = 1;
while (exponent > 0) {
if ((exponent & 1) == 1)
result = (result * base) % modulus;
exponent >>= 1;
base = (base * base) % modulus;
}
return result;
}
溢流你需要使用。这不是因为它溢出,而是因为
7^23
不能精确地表示为double。biginger甚至必须在一个中精确地表示step@Felk编辑答案,谢谢!你的回答中有一句不正确的话:“数字溢出了两倍”。大约为2.7e19,在double
范围内,但无法以必要的精度表示。所以BigInteger解决方案是最简单的方法。@RalfKleberhoff是的,你是对的。我只是引用了安迪·特纳(Andy Turner)的话。谢谢