Clojure reduce 在函数中会溢出,但在直接传递给 REPL 时不会
Clojure reduce overflows when in function, but not when passed directly into REPL
我在调试显然只有在函数中使用该语句时才会发生的溢出时遇到了很大的麻烦。
这是我的功能:
(defn sum-records
[senset votemap]
(let [voteset (select-keys votemap senset)]
(reduce (fn [v1 v2] (mapv + v1 v1)) (vals voteset))))
问题似乎来自 reduce
行。但是,当我 运行 在数据的 repl 中单独显示该行时,它工作得很好。我已经检查以确保我在 repl 测试的数据确实与函数中变成 voteset
的数据相同。我什至在函数中插入了 println
语句来验证这一点。
我真的被困在这里,非常感谢任何帮助!
你可能有一个整数溢出:
(reduce (fn [v1 v2] (mapv + v1 v1)) (repeat 1000 (range 10)))
=> ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow (Numbers.java:1501)
您必须确保输入数据是其他数据,或者在 +
函数中转换为 bigint,或者使用支持任意精度的@ClojureMostly 指出的 +'。
所有这些方法都有效:
(reduce (fn [v1 v2] (mapv +' v1 v1)) (repeat 1000 (range 0 10)))
=> [0N 535754303593133660474212524...
(reduce (fn [v1 v2] (mapv + v1 v1)) (repeat 1000 (range 0N 10N)))
=> [0N 535754303593133660474212524...
(reduce (fn [v1 v2] (mapv + v1 v1)) (repeat 1000 (map bigint (range 10))))
=> [0N 5357543035931336604742125245300009052...
(reduce (fn [v1 v2] (mapv #(+ (bigint %1) (bigint %2)) v1 v1)) (repeat 1000 (range 10)))
=> [0N 53575430359313366...
我在调试显然只有在函数中使用该语句时才会发生的溢出时遇到了很大的麻烦。
这是我的功能:
(defn sum-records
[senset votemap]
(let [voteset (select-keys votemap senset)]
(reduce (fn [v1 v2] (mapv + v1 v1)) (vals voteset))))
问题似乎来自 reduce
行。但是,当我 运行 在数据的 repl 中单独显示该行时,它工作得很好。我已经检查以确保我在 repl 测试的数据确实与函数中变成 voteset
的数据相同。我什至在函数中插入了 println
语句来验证这一点。
我真的被困在这里,非常感谢任何帮助!
你可能有一个整数溢出:
(reduce (fn [v1 v2] (mapv + v1 v1)) (repeat 1000 (range 10)))
=> ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow (Numbers.java:1501)
您必须确保输入数据是其他数据,或者在 +
函数中转换为 bigint,或者使用支持任意精度的@ClojureMostly 指出的 +'。
所有这些方法都有效:
(reduce (fn [v1 v2] (mapv +' v1 v1)) (repeat 1000 (range 0 10)))
=> [0N 535754303593133660474212524...
(reduce (fn [v1 v2] (mapv + v1 v1)) (repeat 1000 (range 0N 10N)))
=> [0N 535754303593133660474212524...
(reduce (fn [v1 v2] (mapv + v1 v1)) (repeat 1000 (map bigint (range 10))))
=> [0N 5357543035931336604742125245300009052...
(reduce (fn [v1 v2] (mapv #(+ (bigint %1) (bigint %2)) v1 v1)) (repeat 1000 (range 10)))
=> [0N 53575430359313366...