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
方法更快。