尽管使用BigInt,但在Clojure计算中溢出

时间:2013-10-31 15:40:44

标签: clojure integer-arithmetic

尽管使用了大整数,但以下闭包计算会溢出:

(defn binomial-coefficient [n k]
  (let [rprod (fn [a b] (reduce * (range a (inc b))))]
    (/ (rprod (- n k -1) n) (rprod 1 k))))

(binomial-coefficient 100N 50N)

我无法弄清楚溢出发生的位置。例如,单独执行rprod似乎有效。

注意:二项系数代码取自Rosetta Code

1 个答案:

答案 0 :(得分:4)

问题是,您使用整数(rprod 1 k)调用1而不是bigint 1N

(defn binomial-coefficient [n k]
  (let [rprod (fn [a b] (reduce * (range a (inc b))))]
    (/ (rprod (- n k -1) n) (rprod 1N k))))

(binomial-coefficient 100N 50N)

问题出在range函数:

=> (range 1 10N)
(1 2 3 4 5 6 7 8 9)
=> (range 1N 10)
(1N 2N 3N 4N 5N 6N 7N 8N 9N)

替代解决方案是使用*'-'inc'代替普通*-inc运算符,因为它们具有内置支持任意精度,永不溢出:

(defn binomial-coefficient [n k]
  (let [rprod (fn [a b] (reduce *' (range a (inc' b))))]
    (/ (rprod (-' n k -1) n) (rprod 1 k))))

(binomial-coefficient 100 50)