请分享您的想法,参与 Clojure 2024 状态调查!

欢迎!请查看关于页面以获取更多关于本站工作方式的信息。

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 设计得比双精度运算更严格似乎是一个错误;明确抛出 ArithmeticException 而不留给 JVM 处理,似乎是多此一举。

0

评论由:csm 提出

我认为这里的问题是 clojure.lang.Numbers 中不同版本的 divide 有不同的语义。Numbers.divide(Object, Object) 执行 isZero 检查,但 Numbers.divide(long, double) 不执行(它只是使用 Java 的除法运算符,因为除数是一个值为 0.0 的双精度浮点数,所以结果是无穷大)。

类似 (/ 1 0.0) 的语句会被编译成调用 Numbers.divide(long, double),因此结果是无穷大。如果第二个参数是函数调用或 var,它看起来像 Object,所以它会被编译成使用 Numbers.divide(Object, Object),并且当第二个参数为零时抛出异常(实际上它编译成调用 Numbers.divide(long, Object),但这只是将第一个参数装箱并调用另一种变体)。

似乎在编译时根据推断的类型对除法具有不同的语义是不正确的;然而,我不知道这是否会影响除零之外的任何其他除法实例,因此这可能是微不足道的问题。

0

评论由:timmc 提出

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

我认为只有偶尔失败的代码更糟糕,因为这样在开发中更容易发现错误,而不是在生产中。

0
参考: https://clojure.atlassian.net/browse/CLJ-1142(由timmc报告)
...