如何在Clojure中获得精确的大数算术结果?

时间:2016-09-17 04:31:04

标签: clojure common-lisp

(这可能是一个愚蠢的问题,但是......)

在Common Lisp中,我可以做类似

的事情
CL-USER> (expt 2 63)
9223372036854775808

我为Clojure尝试了一些替代方案:

user> (Math/pow 2 63)
9.223372036854776E18

显然,胁迫int不起作用:

user> (int (Math/pow 2 63))
IllegalArgumentException Value out of range for int: 9.223372036854776E18  clojure.lang.RT.intCast (RT.java:1211)

所以我尝试强迫bigint

user> (bigint (Math/pow 2 63))
9223372036854776000N

......但这也不起作用。

获得与上述相同结果的推荐方法是什么? (谢谢!)

2 个答案:

答案 0 :(得分:5)

您可以使用BigDecimal中的pow

user=> (.pow (bigdec 2) 63)
9223372036854775808M

至于处理bigdec / bigint Clojure,还有" auto promote"具有尾随'的计算函数(例如*')。对于其他操作,Java interop始终是选项或第三方库,如https://github.com/clojure/math.numeric-tower

答案 1 :(得分:4)

Clojure使用Java数学(双精度),就像你为大多数事情所做的那样。如果你想使用任意精度数学,你可以使用BigDecimal类编写自己的简单函数:

(defn my-pow [x y]
  (apply * (repeat y (bigdec x))))

(println (my-pow 2 63))

> lein run
(my-pow 2 63) => 9223372036854775808M