I wrote this line of code:
System.out.println(Math.pow(7, 23) % 143); // 7^23 mod 143
I expected the output to be 2
but the output was 93.0
. Does someone know what I'm doing wrong?
I wrote this line of code:
System.out.println(Math.pow(7, 23) % 143); // 7^23 mod 143
I expected the output to be 2
but the output was 93.0
. Does someone know what I'm doing wrong?
The number "overflows" double
, which is what Math.pow()
expects and returns. Use a BigInteger
instead:
BigInteger.valueOf(7)
.pow(23)
.mod(BigInteger.valueOf(143))
Or in a single step, as suggested by @Felk:
BigInteger.valueOf(7)
.modPow(BigInteger.valueOf(23), BigInteger.valueOf(143))
The result of Math.pow
is a double
, which has 64 bits; 53 of those are mantissa bits. This means that any integer greater than 2^53-1 = 9007199254740991
can't be represented precisely as a double.
7^23 is larger than 2^53-1 (it's just a bit larger than 2^64, actually), so it can't be represented precisely. As such, the result of the %
is not what you expect.
Use BigInteger
instead, as @Costi has already suggested.
Use a Modular exponentiation algorithm if the intermediate exponentiation result is too large to hold in a variable.
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;
}