Java 7的BigInteger操作有多复杂?

时间:2010-01-28 11:33:47

标签: java complexity-theory biginteger java-7

目前multiply中的方法dividepowBigInteger有多复杂?没有提到文档中的计算复杂性(也没有提到其他任何地方)。

4 个答案:

答案 0 :(得分:3)

如果您查看BigInteger(随JDK提供)的代码,我觉得可以 multiply(..) O(n ^ 2)(实际上该方法为multiplyToLen(..))。其他方法的代码有点复杂,但你可以看到自己。

注意:这适用于Java 6.我假设它在Java 7中没有区别。

答案 1 :(得分:2)

测量它。使用线性增加操作数进行操作并在图上绘制时间。 不要忘记预热JVM(多次运行)以获得有效的基准测试结果。

如果操作是线性O(n),则二次O(n ^ 2),多项式或指数应该是显而易见的。

编辑:虽然您可以给出算法理论界限,但它们在实践中可能不那么有用。首先,复杂性并没有给出因素。一些线性或子二次算法根本没用,因为它们吃了太多的时间和资源,以至于它们不适合手头的问题(例如Coppersmith-Winograd矩阵乘法)。 然后你的计算可能有你只能通过实验检测到的所有kludges。有一些准备算法无法解决问题,但加速真正的求解器(矩阵调节)。有一些次优的实现。如果长度较长,速度可能会急剧下降(缓存丢失,内存移动等)。所以出于实际目的,我建议做实验。

最好的是每次输入的长度加倍并比较时间。 是的,你找出算法是否具有n ^ 1.5或n ^ 1.8复杂度。简单四倍 输入长度,你只需要1.5的半个时间而不是2.如果你将长度乘以256倍,你将再次获得1.8的时间。

答案 2 :(得分:2)

有一个新的“更好”的BigInteger类没有被sun jdk用于保守主义和缺乏有用的回归测试(庞大的数据集)。做出更好算法的人可能会在评论中讨论过旧的BigInteger。

在这里你http://futureboy.us/temp/BigInteger.java

答案 3 :(得分:1)

正如对@Bozho's answer的评论所指出的,与Java 7和更早版本中的朴素O(N^2)算法相比,Java 8及更高版本使用更高效的算法来实现乘法和除法。

Java 8乘法根据被乘数的大小自适应地使用朴素的O(N^2)长乘法,Karatsuba algorithm或三向Toom-Cook algorithm。后者分别是O(N^1.58)O(N^1.46)

Java 8除法自适应地使用Knuth的O(N^2)长除法算法或Burnikel-Ziegler algorithm。 (根据研究论文,后者是2K(N) + O(NlogN),用于将2N位数字除以N位数字,其中K(N)是两个N位数字的唐津乘法时间。)

同样,其他一些操作也得到了优化。


在文档中(也没有其他地方)没有提到计算复杂性。

Java 8源代码中提到了一些复杂性的细节。 javadocs之所以没有提及复杂性,是因为它在理论上和实践上都是特定于实现的。 (事实证明,某些操作的复杂性在Java 7和8之间存在很大差异。)