Invalid conversion from BigDecimal to long using clojure.core/long

Description

Trying to convert from BigDecimal to long

let's just use BigDecimal.longValue()

looking into clojure.lang.RT and suspecting incorrect conversion chain

Cause: long cast from BigDecimal will use Number.longValue(), which in this case produces an incorrect value even though the conversion is possible. The javadoc indicates that this call is equivalent to a double to long conversion and is potentially lossy in several ways.

Approach: add explicit case in long cast to handle BigDecimal and instead call longValueExact(). Patch adds additional cast tests for some BigInteger and BigDecimal values. The unchecked-long cast does not seem to be affected (returned the proper value with no changes).

Questions: while it may be confusing, the incorrect result may actually be the one that is consistent with Java. unchecked-long would give the expected result and may be the better choice for the example here. So it's possible that we should NOT apply this patch and instead do nothing. If we do move forward with the patch, we may want to also apply an equivalent change to call byteValueExact(), shortValueExact(), intValueExact(), and toBigIntegerExact() in the appropriate places as well.

Patch: clj-2001.patch

Environment

Ubuntu Linux 15

Activity

Show:
Alex Miller
August 10, 2016, 1:36 AM

Indeed that's a possibility, although I think it's probably rare in this case.

Ghadi Shayban
August 9, 2016, 4:07 PM

Patch seems like it may negatively affect inlining

Alex Miller
August 9, 2016, 2:14 PM

Yeah, RT.longCast() doesn't seem to explicitly handle BigDecimal.

Your pinned fields
Click on the next to a field label to start pinning.

Assignee

Unassigned

Reporter

import

Labels

Approval

Triaged

Patch

Code and Test

Priority

Major

Affects versions