2024 Clojure 状态调查! 中分享您的想法。

欢迎!请查看 关于 页面以了解更多此网站的信息。

0
Java 交互操作

clojure.core// 的单目调用将 0.0 这个被除数,与双目调用的处理方式不同,这很可能是由于内联引起的。

(/ 0.0) ;; java.lang.ArithmeticException: Divide by zero (/ 1 0.0) ;;= Infinity (/ 1 (identity 0.0)) ;; java.lang.ArithmeticException: Divide by zero

4 个答案

0

由:timmc

相关的代码似乎就是 clojure.lang.Numbers/divide 中的这个

if(yops.isZero((Number)y)) throw new ArithmeticException("Divide by zero");

让 Numbers/divide 比 double 算术更具限制性似乎像是一个错误;显式抛出 ArithmeticException 而不是让 JVM 来确定,似乎是多此一举。

0

由:csm

我认为这里是 clojure.lang.Numbers 中不同除法版本的语义不同。Numbers.divide(Object, Object) 会执行 isZero 检查,而 Numbers.divide(long, double) 不会(它只使用 Java 的除法运算符,由于除数是一个值为 0.0 的 double,所以产生 Infinity)。

类似于 (/ 1 0.0) 的语句将被编译为调用 Numbers.divide(long, double),因此会产生 Infinity。如果第二个参数是函数调用或 var,它看起来像一个 Object,所以它将被编译为使用 Numbers.divide(Object, Object),并且那个调用在第二个参数为零时会抛出异常(实际上它编译为对 Numbers.divide(long, Object) 的调用,但这只是将第一个参数装箱并调用另一个版本)。

基于编译时推断的类型进行不同的除法语义似乎是错误的;但是,我不知道这是否影响除以零之外的其他除法实例,所以这可能不是真正的问题。

0

由:timmc

bq. 我不知道这会不会影响除零除法之外的其他任何除法实例,因此可能不是一个实际问题。

我认为只会在某些情况下失败的代码更糟糕,因为此时错误更有可能在生产环境中而不是在开发中被捕获。

0
...