# Clojure

## double division by zero inconsistency

### Details

• Type: Defect
• Status: Open
• Priority: Minor
• Resolution: Unresolved
• Affects Version/s: Release 1.9
• Fix Version/s: None
• Component/s: None
• Labels:
• Approval:
Triaged

### Description

Division by zero with doubles will throw an exception if both arguments are boxed, but not otherwise:

Clojure 1.9.0-beta1
user=> (/ 5.0 0.0)
##Inf
user=> (/ (identity 5.0) 0.0)
##Inf
user=> (/ 5.0 (identity 0.0))
##Inf
user=> (/ (identity 5.0) (identity 0.0))
ArithmeticException Divide by zero  clojure.lang.Numbers.divide (Numbers.java:163)

### Activity

Hide
Erik Assum added a comment -

So, I guess some division by zero is somewhat undefined.
If one removes

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

then

(/ (identity 5.0) (identity 0.0))

returns infinity as the unboxed versions.

Although doing so, also causes a change to

(/ 5 0)

which then becomes `1/0`, whereas it previously threw Divide by zero.

From Numbers.java we see that unboxed math does not protect against division by zero:

static public double divide(double x, double y){
return x / y;
}

whereas boxed versions do:

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);
}

This inconsistency is also reproducible with 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: (source function-name-here)
Exit: Control+D or (exit) or (quit)
Results: Stored in vars *1, *2, *3, an exception in *e

user=> (/ 5.0 0.0)
Infinity
user=> (/ (identity 5.0) (identity 0.0))

ArithmeticException Divide by zero  clojure.lang.Numbers.divide (Numbers.java:158)
user=>
Show
Erik Assum added a comment - So, I guess some division by zero is somewhat undefined. If one removes
if(yops.isZero((Number)y))
throw new ArithmeticException("Divide by zero");
then
(/ (identity 5.0) (identity 0.0))
returns infinity as the unboxed versions. Although doing so, also causes a change to
(/ 5 0)
which then becomes `1/0`, whereas it previously threw Divide by zero. From Numbers.java we see that unboxed math does not protect against division by zero:
static public double divide(double x, double y){
return x / y;
}
whereas boxed versions do:
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);
}
This inconsistency is also reproducible with 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: (source function-name-here)
Exit: Control+D or (exit) or (quit)
Results: Stored in vars *1, *2, *3, an exception in *e

user=> (/ 5.0 0.0)
Infinity
user=> (/ (identity 5.0) (identity 0.0))

ArithmeticException Divide by zero  clojure.lang.Numbers.divide (Numbers.java:158)
user=>
Hide
Erik Assum added a comment -

Any thoughts on an approach?
Both throwing on division by zero for natives and allowing it for boxed seems to be a serious change, and the tests expects an exception for boxed division by zero.

Show
Erik Assum added a comment - Any thoughts on an approach? Both throwing on division by zero for natives and allowing it for boxed seems to be a serious change, and the tests expects an exception for boxed division by zero.

Vote (0)
Watch (1)

• Created:
Updated: