Clojure

divide(Object, Object) with (NaN, 0) does not return NaN

Details

  • Type: Defect Defect
  • Status: Reopened Reopened
  • Priority: Trivial Trivial
  • Resolution: Unresolved
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
  • Patch:
    Code and Test
  • Approval:
    Prescreened

Description

Would expect both of these to return NaN but first does not:

user=> (def x Double/NaN)
#'user/x
user=> (/ x 0)

ArithmeticException Divide by zero  clojure.lang.Numbers.divide (Numbers.java:156)
user=> (/ Double/NaN 0)
Double/NaN

Cause: Here we are dividing a double by a long. In the first case, this is parsed as divide(Object, long) which then calls divide(Object, Object), which throws ArithmeticException if the second arg is 0 (regardless of the first arg).

In the second case it's parsed as divide(double, long) which just relies on Java to properly upcast the primitive long to a double to do the divide.

Note that making this call with 2 doubles does return NaN:

user=> (def x Double/NaN)
#'user/x
user=> (/ x 0.0)
NaN

or type hinting x to a double works as well:

user=> (def x Double/NaN)
#'user/x
user=> (/ ^double x 0.0)
NaN

Proposed: Add checks in divide(Object, Object) to check whether x is NaN and instead return NaN.

Patch: fix-clj-1371.patch
Prescreened by: Alex Miller

Activity

Alex Miller made changes -
Field Original Value New Value
Status Open [ 1 ] Closed [ 6 ]
Resolution Declined [ 2 ]
Alex Miller made changes -
Resolution Declined [ 2 ]
Status Closed [ 6 ] Reopened [ 4 ]
Alex Miller made changes -
Priority Major [ 3 ] Trivial [ 5 ]
Alex Miller made changes -
Labels math
Alex Miller made changes -
Summary Weird NaN behavior divide(Object, Object) with (NaN, 0) does not return NaN
Pavlos Vinieratos made changes -
Attachment fix-clj-1371.patch [ 16028 ]
Alex Miller made changes -
Priority Trivial [ 5 ] Minor [ 4 ]
Approval Prescreened [ 10220 ]
Patch Code and Test [ 10002 ]
Alex Miller made changes -
Description user=> (def x Double/NaN)
#'user/x
user=> (/ x 0)

ArithmeticException Divide by zero clojure.lang.Numbers.divide (Numbers.java:156)
user=> (/ Double/NaN 0)
Double/NaN
{code}
user=> (def x Double/NaN)
#'user/x
user=> (/ x 0)

ArithmeticException Divide by zero clojure.lang.Numbers.divide (Numbers.java:156)
user=> (/ Double/NaN 0)
Double/NaN
{code}

*Cause:* Here we are dividing a double by a long. In the first case, this is parsed as divide(Object, long) which then calls divide(Object, Object), which throws ArithmeticException if the second arg is 0 (regardless of the first arg).

In the second case it's parsed as divide(double, long) which just relies on Java to properly upcast the primitive long to a double to do the divide.

Note that making this call with 2 doubles does return NaN:

{code}
user=> (def x Double/NaN)
#'user/x
user=> (/ x 0.0)
NaN
{code}

or type hinting x to a double works as well:

{code}
user=> (def x Double/NaN)
#'user/x
user=> (/ ^double x 0.0)
NaN
{code}

*Proposed:* Add checks in divide(Object, Object) to check whether x is NaN and instead return NaN.

*Patch:* fix-clj-1371.patch
*Prescreened by:* Alex Miller
Alex Miller made changes -
Priority Minor [ 4 ] Trivial [ 5 ]
Description {code}
user=> (def x Double/NaN)
#'user/x
user=> (/ x 0)

ArithmeticException Divide by zero clojure.lang.Numbers.divide (Numbers.java:156)
user=> (/ Double/NaN 0)
Double/NaN
{code}

*Cause:* Here we are dividing a double by a long. In the first case, this is parsed as divide(Object, long) which then calls divide(Object, Object), which throws ArithmeticException if the second arg is 0 (regardless of the first arg).

In the second case it's parsed as divide(double, long) which just relies on Java to properly upcast the primitive long to a double to do the divide.

Note that making this call with 2 doubles does return NaN:

{code}
user=> (def x Double/NaN)
#'user/x
user=> (/ x 0.0)
NaN
{code}

or type hinting x to a double works as well:

{code}
user=> (def x Double/NaN)
#'user/x
user=> (/ ^double x 0.0)
NaN
{code}

*Proposed:* Add checks in divide(Object, Object) to check whether x is NaN and instead return NaN.

*Patch:* fix-clj-1371.patch
*Prescreened by:* Alex Miller
Would expect both of these to return NaN but first does not:

{code}
user=> (def x Double/NaN)
#'user/x
user=> (/ x 0)

ArithmeticException Divide by zero clojure.lang.Numbers.divide (Numbers.java:156)
user=> (/ Double/NaN 0)
Double/NaN
{code}

*Cause:* Here we are dividing a double by a long. In the first case, this is parsed as divide(Object, long) which then calls divide(Object, Object), which throws ArithmeticException if the second arg is 0 (regardless of the first arg).

In the second case it's parsed as divide(double, long) which just relies on Java to properly upcast the primitive long to a double to do the divide.

Note that making this call with 2 doubles does return NaN:

{code}
user=> (def x Double/NaN)
#'user/x
user=> (/ x 0.0)
NaN
{code}

or type hinting x to a double works as well:

{code}
user=> (def x Double/NaN)
#'user/x
user=> (/ ^double x 0.0)
NaN
{code}

*Proposed:* Add checks in divide(Object, Object) to check whether x is NaN and instead return NaN.

*Patch:* fix-clj-1371.patch
*Prescreened by:* Alex Miller

People

Vote (0)
Watch (4)

Dates

  • Created:
    Updated: