尝试从 BigDecimal 转换为 long
(long 201608081812113241M) => 201608081812113248 ;; 事实上这不是我们的数字
让我们直接使用 BigDecimal.longValue()
(.longValue 201608081812113241M) => 201608081812113241 ;; 好的,准确值
检查 clojure.lang.RT,怀疑转换链有误
(.longValue (.doubleValue 201608081812113241M)) => 201608081812113248 ;; 对,错误
原因: 从 BigDecimal 到 long 的转换将使用 Number.longValue(),尽管转换是可能的,但在此情况下会产生不正确的值。javadoc 表明此调用相当于 double 到 long 的转换,并且在某些方面可能是有损的。
方法: 在 long 转换中添加显式的案例来处理 BigDecimal,并调用 longValueExact()。补丁为一些 BigInteger 和 BigDecimal 值添加了额外的转换测试。未检查的 long 转换似乎不受影响(返回了正确的值,没有变化)。
问题: 虽然这可能令人困惑,但错误的结果实际上可能与 Java 一致。unchecked-long 将给出预期的结果,可能是这里的更好选择。因此,我们可能应该不应用此补丁而什么也不做。如果我们继续推进补丁,我们也可能想要在同一地点应用调用 byteValueExact()、shortValueExact()、intValueExact() 和 toBigIntegerExact() 的等效更改。
补丁: clj-2001.patch