尝试将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一致的值。未经检查的长值将给出预期的结果,并可能是这里的更好选择。因此,我们可能不应该应用此补丁,而应该什么都不做。如果我们继续进行补丁,我们也可能希望在某些适当位置应用等效更改来调用byteValueExact()、shortValueExact()、intValueExact()以及toBigIntegerExact()。
补丁:clj-2001.patch