我注意到,在使用 Java 的 BigInteger 类时,基本算术运算似乎比它们的原始运算效率低得多,即使使用相同的数字和运算也是如此。使用数字的 BI 表示的算法比使用相同数字的长表示的完全相同的算法花费的时间要多得多。
为了说明我的意思,我提供了一个工作代码示例。在下面的示例中,我简单地遍历了 1 到 1000000000 之间的所有整数,对每次迭代执行 mod 2 操作,然后打印出循环的总运行时间。我首先使用 long,然后使用 BigInteger:
import java.math.BigInteger;
public class FunWithNumbers {
public static void main(String[] args) {
long myNumL = 100000000L; // Long representation of some number n
BigInteger myNumB = new BigInteger("100000000"); // BI representation of same number
/* long version */
long startTime = System.nanoTime();
for (long i=1L; i<= myNumL; i++) {
long a = myNumL % 2;
}
System.out.println("Total computation time (long representation): " +
(System.nanoTime() - startTime)*Math.pow(10, -9) + " seconds.");
/* BI version */
startTime = System.nanoTime();
BigInteger index = new BigInteger("1");
while (!index.equals(myNumB)) {
BigInteger b = myNumB.remainder(index);
index = index.add(BigInteger.ONE);
}
System.out.println("Total computation time (BI representation): " +
(System.nanoTime() - startTime)*Math.pow(10, -9) + " seconds.");
}
}
这会生成以下输出:
总计算时间(长表示):0.035671096 秒。
总计算时间(BI 表示):7.031978092 秒。
如您所见,运行时间甚至无法进行远程比较。我的问题是我需要处理太大而无法放入“长”数据类型的数字。
有没有办法恢复原始算术的效率,并且仍然能够处理超过 long 的最大大小的任意大数字?
如果需要的话,我可以切换到另一种语言;我绝不会被 Java 束缚。