Java ArithmeticException BigInteger会溢出支持的范围

时间:2015-04-09 19:22:20

标签: java range overflow biginteger arithmeticexception

我正在研究一种算法,以检查数字是否为素数,需要使用非常大的数字,因此我使用的是BigInteger类。问题是抛出了这个异常 ArithmeticException BigInteger会溢出支持的范围

Exception in thread "main" java.lang.ArithmeticException: BigInteger would overflow supported range
    at java.math.BigInteger.reportOverflow(Unknown Source)
    at java.math.BigInteger.checkRange(Unknown Source)
    at java.math.BigInteger.<init>(Unknown Source)
    at java.math.BigInteger.shiftLeft(Unknown Source)
    at java.math.BigInteger.pow(Unknown Source)
    at Kitas.main(Kitas.java:118)

引发异常的行:

b = BigInteger.valueOf(2).pow((int) (35*(Math.pow(2, counter))));

一旦计数器达到值26,就会抛出异常。

2 个答案:

答案 0 :(得分:4)

(int) (35 * Math.pow(2, 26)) == (int) (2348810240d) = Integer.MAX_VALUE

结果是您尝试将2提升到的功率为Integer.MAX_VALUE,因此结果将超过Integer.MAX_VALUE二进制数字。 BigInteger对此并不够大,存储大数字是非常不切实际的。

Java中没有任何内容可以让你测试大数字的素数。

答案 1 :(得分:1)

BigInteger使用int[]来存储数组的值。这意味着该数字不能大于2 ^(Integer.Max_Value),因为任何大于该值的数组都会使数组的索引(存储在单个int中)大于数组的最大大小。

在26,您存储的号码是:

2^(35*[2^26]) = 2^2348810240 

此处使用的2的幂(2,348,810,240)略大于(2 ^ 31-1),这是由于BigInteger的内部存储器的实现而可以存储在BigInteger中的最大值。超过26的计数器只会使这个问题变得更糟。

如果你真的需要使用这么大的数字,你可能需要编写自己的BigInteger版本,它使用其他东西来存储它的值,这允许更多的存储空间。也许像这样的二维数组:int[][] storage,因为它可以保存最多2 ^(2 ^(2 ^ 32-1)-1)的值。如果你需要更多,你可以继续增加阵列的尺寸,直到你的计算机内存不足为止 - 如果完全填充int [] []不会已经这样做(我怀疑它会)。

有关详细信息,请参阅documentation