BigInteger 的乘法與平行乘法方法
1. 概述
有時,在使用 Java 程式設計時,我們可能需要使用超出基本型別(如long型別)限制的整數值。 BigInteger類別允許我們做到這一點。例如,我們需要使用BigInteger類別來計算100的階乘。
BigInteger類別提供了兩個公共乘法方法, multiply和parallelMultiply 。儘管它們的用法相似並且返回相同的數學結果,但在某些情況下,其中一種可能比另一種更好。
在本教學中,我們將比較BigInteger類別的multiply和parallelMultiply方法。
2. multiply
BigInteger類別的multiply方法將兩個BigInteger實例相乘。讓我們看一個範例,展示如何使用此方法:
BigInteger bigInteger1 = new BigInteger("131224324234234234234313");
BigInteger bigInteger2 = new BigInteger("13345663456346435648234313");
BigInteger result = bigInteger1.multiply(bigInteger2);
建立兩個BigInteger實例bigInteger1和bigInteger2後,我們使用multiply( )方法將它們相乘。我們將乘法的結果指派給result變量,該變數也是BigInteger類型。
parallelMultiply方法
BigInteger類別的parallelMultiply方法是用於將兩個BigInteger實例相乘的另一種選擇。其用法與multiply方法的用法類似:
BigInteger bigInteger1 = new BigInteger("131224324234234234234313");
BigInteger bigInteger2 = new BigInteger("13345663456346435648234313");
BigInteger result = bigInteger1.parallelMultiply(bigInteger2);
該方法從 Java 19 開始可用。
4. 實現比較
我們首先來比較兩種方法的實作。 BigInteger.java中的公用multiply方法呼叫私有multiply方法:
public BigInteger multiply(BigInteger val) {
return multiply(val, false, false, 0);
}
parallelMultiply方法也呼叫相同的私有multiply方法:
public BigInteger parallelMultiply(BigInteger val) {
return multiply(val, false, true, 0);
}
它們之間的差異是multiply第三個參數的值。第一個是false而第二個是true 。讓我們檢查私有multiply方法的簽章及其回傳類型:
private BigInteger multiply(BigInteger val, boolean isRecursion, boolean parallel, int depth)
第三個參數的名稱是parallel 。此參數指定乘法運算是否並行進行。
事實上, multiply方法透過根據乘數和被乘數的值使用不同的演算法來加速乘法過程。對於大數,它使用Karatsuba 演算法;對於由數千位組成的大數,它使用三路 Toom-Cook 演算法。
三路Toom Cook演算法可以將兩個大整數拆分為較小的整數,並並行化較小整數的乘法。因此,它降低了計算時間複雜度,從而加快了計算速度。因此,在乘以大數時,我們可能更喜歡使用parallelMultiply方法。但是, parallelMultiply方法可能會使用更多的 CPU 和記憶體來更快地計算乘法。
根據報告的測試結果,使用parallelMultiply計算第100000000 個斐波那契數可能比使用multiply快2.75 倍。
5. 結論
在本文中,我們比較了BigInteger類別的multiply和parallelMultiply方法。首先,我們看到了這兩種方法的用法。它們的用法是一樣的。
然後,我們簡要討論了它們的實作細節。我們看到他們在幕後使用了相同的私有multiply方法。然而, parallelMultiply方法使用三路 Toom-Cook 方法的平行實作來處理大整數。因此,對於由數千位組成的整數,它比multiply方法更快。