2013-08-02 17 views
11

我正在尋找Clojure中何時使用Clojure BigInt與Java BigInteger的指導。兩者都工作得很好,我假設使用BigInt的主要原因是利用諸如+=等運算符,這些運算符必須通過Java實例方法.add.equals進行訪問。但是我只能從BigInteger訪問的運營商很少,如isProbablePrimeBigInt與BigInteger在Clojure中的使用案例

從BigInt轉換到BigInteger似乎很容易,反之亦然,但兩者的存在使得用例不清楚。在沒有明確標準的情況下,我的膝蓋反應只是堅持BigInteger,因爲一些建議的用法看起來不起作用。從clojuredocs here

user=> (def x (bigint 97)) 
user=> (.isProbablePrime x 1) 
IllegalArgumentException No matching method found: isProbablePrime for class  
clojure.lang.BigInt clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:53) 
+1

查看BigInt的源代碼(https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/BigInt.java)後,它看起來像一個BigInt包含兩個java.math.Bigint和long。在Clojure網頁上,它表示BigInts在所有操作中保持其類型。考慮到你可以使用.toBigInteger和.fromBigInteger輕鬆進行投射,以防你想使用isProbablePrime等方法,同時考慮到構建java.math.BigInteger並不容易,我會堅持使用bigint並投射出來如果必要的話回來(BigInts自己做,例如.add)。 –

+0

它實際上是'clojure.lang.BigInt/fromBigInteger';我在這裏添加了一個例子http://clojuredocs.org/clojure_core/clojure.core/bigint –

+0

您是否偶然使用盧卡斯數字? – Carcigenicate

回答

22

在「Clojure編程」由C. Emerick et。在第428頁中,有一個側欄主題,「當Java已經在BigInteger中提供了一個時,爲什麼Clojure擁有自己的BigInt類?」

他們注意到兩個理由更喜歡BigInt Java的BigInteger。首先,後者的.hashCode實現與Long的實現不一致(每種類型中表示的相同數字給出不同的哈希值)。在比較等效值時,這通常不是你想要的。哈希映射。

另一個原因是BigInt被優化爲儘可能使用原始類型,因此在許多情況下性能應該更好。

我會使用Clojure的數字類型,除非你有一個很好的理由不要(你使用.isProbablePrime表明你可能有足夠的理由)。

+1

謝謝你的出色答案。他們應該在文檔中寫下這些東西。 –

+3

我認爲'hash-code'和像'range'這樣的其他運算符的連續性是造成BigInt偏差的充分原因。我可以爲諸如'.isProbablePrime'之類的東西創建一個橋接操作的小型庫。這個策略會給我一個更小的庫,因爲在另一方面,我開始習慣於在BigInteger上編寫整個數學庫,例如'big-range','big-le'等。 –