Trying to convert from BigDecimal to long
(long 201608081812113241M)
=> 201608081812113248 ;; not really our number
let's just use BigDecimal.longValue()
(.longValue 201608081812113241M)
=> 201608081812113241 ;; ok, correct value
looking into clojure.lang.RT and suspecting incorrect conversion chain
(.longValue (.doubleValue 201608081812113241M))
=> 201608081812113248 ;; yep, incorrect
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