Reputation: 373
I have two simple java codes.The first one defines constant power as power = a.pow(b);
import java.math.BigInteger;
public class FermatOne
{
public static void main(String[] args)
{
BigInteger a = new BigInteger ("2");
BigInteger k = new BigInteger ("15");
BigInteger c = new BigInteger ("1");
int b = 332192810;
BigInteger n = new BigInteger ("2");
BigInteger power;
power = a.pow(b);
BigInteger exponent;
exponent = k.multiply(power);
BigInteger mod;
mod = exponent.add(c);
BigInteger result = n.modPow(exponent,mod);
System.out.println("Result is ==> " + result);
}
}
The second one defines constant power as power = BigInteger.ONE.shiftLeft(b)
import java.math.BigInteger;
public class FermatOne
{
public static void main(String[] args)
{
BigInteger k = new BigInteger ("15");
BigInteger c = new BigInteger ("1");
int b = 332192810;
BigInteger n = new BigInteger ("2");
BigInteger power;
power = BigInteger.ONE.shiftLeft(b);
BigInteger exponent;
exponent = k.multiply(power);
BigInteger mod;
mod = exponent.add(c);
BigInteger result = n.modPow(exponent,mod);
System.out.println("Result is ==> " + result);
}
}
Setting the memory flag -Xmx1024m in the command line the first code works fine , but for the second code I am getting error : java.lang.OutOfMemoryError :Java heap space
My question : What should I change in the second code to avoid java.lang.OutOfMemoryError ?
Upvotes: 1
Views: 1557
Reputation: 221210
You're trying to calculate a number like 2 ^ (15 * 2 ^ 332192809)
. I don't know if you could even fit such a number in the universe!! Or maybe, the answer is simply... 42
? ;-)
On a more serious note, you'll really have trouble, calculating this number. Encoded in bits, 15 * 2 ^ 332192810
would require almost a gigabyte by itself. Then raising 2
to that power again, I don't want to know...
On a more serious note, when you dig into the implementation of java.math.BigInteger
, I think that you just run into such an error faster with the left shift, as that is implemented much more efficiently, than the power method. Having said this, have you tried to force garbage collection in your code, using System.gc()
?
UPDATE: My original reasoning might've been wrong. 2 ^ 332192809
can be calculated with 1GB. And the overall result might be "modded" efficiently by java.math.BigInteger
, although I believe that this calculation might take a while...
Upvotes: 6
Reputation: 88747
It's just a guess, but BigInteger.ONE.shiftLeft(332192810);
will internally create an int
array of length x + 10381025
. Since an int is 4 bytes big you'll get about 40 mega bytes of data just for that one call. I assume the other calls copy that data around and thus you get that high a memory consumption.
Upvotes: 1