commented by: slipset
所以,我认为某些除以零的运算可能是未定义的。
如果移除
`
if(yops.isZero((Number)y))
throw new ArithmeticException("Divide by zero");
`
然后
(/ (identity 5.0) (identity 0.0))
将返回作为未装箱版本的无限大。
尽管这样做,也会更改
(/ 5 0)
它变成了1/0
,而之前会抛出除以零异常。
从 Numbers.java 我们可以看到,未装箱数学运算不对除以零进行保护
`
static public double divide(double x, double y){
return x / y;
}
`
而装箱版本的则做保护
`
static public Number divide(Object x, Object y){
if (isNaN(x)){
return (Number)x;
} else if(isNaN(y)){
return (Number)y;
}
Ops yops = ops(y);
if(yops.isZero((Number)y))
throw new ArithmeticException("Divide by zero");
return ops(x).combine(yops).divide((Number)x, (Number)y);
}
`
这种不一致性在 Clojure 1.8 中也可重现
`
Clojure 1.8.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_144-b01
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
源代码: (source function-name-here)
JavaDoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
结果:存储在 vars 1, 2, 3, 异常在 e
user=> (/ 5.0 0.0)
无限大
user=> (/ (identity 5.0) (identity 0.0))
ArithmeticException Divide by zero clojure.lang.Numbers.divide (Numbers.java:158)
user=>
`