2013-10-31 38 views
1

下關閉計算溢出儘管使用大整數的:溢出Clojure中的計算,儘管使用BigInt有

(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

回答

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)