3

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

4

2 回答 2

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

结果是您尝试将 2 提高到的幂是 Integer.MAX_VALUE,因此结果将超过 Integer.MAX_VALUE 二进制数字。 BigInteger还不够大,存储这么大的数字是非常不切实际的。

Java 内置的任何内容都无法让您测试如此大的数字的素数。

于 2015-04-09T19:46:40.030 回答
1

BigInteger 使用 anint[]来存储数组的值。这意味着该数字不能大于 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[][] 还不会这样做(我怀疑它会这样做)。

有关更多信息,请参阅文档

于 2015-04-09T19:47:19.243 回答