【问题标题】:use-cases for BigInt versus BigInteger in ClojureClojure 中 BigInt 与 BigInteger 的用例
【发布时间】:2013-08-02 16:29:24
【问题描述】:

我正在寻找有关何时在 Clojure 中使用 Clojure BigInt 与 Java BigInteger 的指导。两者都工作得很好,我假设使用 BigInt 的主要原因是利用像 += 这样的运算符,它们必须通过 Java 实例方法 .add.equals 访问,例如实例。但是很少有操作符,比如isProbablePrime,我只能从BigInteger访问。

从 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)

【问题讨论】:

  • 查看 BigInt (github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/…) 的源代码后,BigInt 似乎包含 java.math.Bigint 和 long。在 Clojure 网页上,它说 BigInts 在所有操作中保持其类型。考虑到您可以使用 .toBigInteger 和 .fromBigInteger 轻松转换,以防您想使用 isProbablePrime 之类的方法,并且考虑到构造为 java.math.BigInteger 并不容易,我会坚持使用 bigint 并进行转换必要时返回(BigInts 自己执行此操作,例如在 .add 中)。
  • 其实是clojure.lang.BigInt/fromBigInteger;我在这里添加了一个示例clojuredocs.org/clojure_core/clojure.core/bigint

标签: clojure


【解决方案1】:

在 C. Emerick 等人的“Clojure 编程”中。 al., p.428,有一个侧边栏主题,“为什么当 Java 已经在 BigInteger 中提供了一个 BigInt 类时,Clojure 有自己的 BigInt 类?”

他们注意到两个原因更喜欢BigInt 而不是Java 的BigInteger。首先,后者的.hashCode实现与Long的实现不一致(每种类型表示的相同数字给出不同的hash值)。在比较等效值时,这通常不是您想要的,例如哈希映射。

另一个原因是BigInts 被优化为尽可能使用原始类型,因此在许多情况下性能应该更好。

我会使用 Clojure 的数字类型,除非你有充分的理由不这样做(你使用 .isProbablePrime 表明你可能有足够的理由)。

【讨论】:

  • 感谢您的出色回答。他们应该在文档字符串中写下这些内容。
  • 我认为hash-code 和其他运营商如range 的连续性是偏向BigInt 的充分理由。我可以为.isProbablePrime 之类的东西制作一个小型的桥接操作库。这种策略总体上会给我一个更小的库,因为在替代方案中,我开始沉迷于在BigInteger 上编写整个数学库,例如big-rangebig-le 等。
猜你喜欢
  • 1970-01-01
  • 2015-02-10
  • 1970-01-01
  • 2011-07-18
  • 2018-11-06
  • 1970-01-01
  • 2019-12-03
  • 2011-10-05
  • 2016-02-26
相关资源
最近更新 更多