Java ArithmeticException BigInteger将溢出支持的范围



我正在研究一种算法来检查数字是否为素数,并且需要处理真正大的数字,因此我使用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,就会引发异常。

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

结果是,你试图将2的幂提高到整数.MAX_VALUE,所以结果将超过整数.MAX-VALUE的二进制数字。BigInteger还不够大,存储那么大的数字是不切实际的。

Java中内置的任何东西都不能让您测试这么大的数字的素性。

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

26时,您存储的号码是:

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

此处使用的二的幂(2348810240)略大于(2^31-1),后者是由于实现了BigInteger的内部存储而可以存储在BigInteger中的最大值。超过26只会让这个问题变得更糟。

如果你真的需要处理这么大的数字,你可能必须编写自己版本的BigInteger,它使用其他东西来存储它的值,这允许更多的存储空间。也许是这样的二维数组:int[][] storage,因为它可以容纳高达2^(2^(2*32-1)-1)的值。如果你需要更多,你可以继续增加数组的大小,直到你的计算机内存用完——如果完全填充int[][]还不能做到这一点(我怀疑会的)。

有关详细信息,请参阅文档。

最新更新