2013-08-02 15 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'等。 –