请在2024 Clojure状态调查!中分享您的想法。

欢迎!请查看关于页面以获取更多关于该方式的信息。

0
Java互操作性

尝试将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

4 个答案

0

评论者:alexmiller

是的,RT.longCast()看起来并没有明确处理BigDecimal。

0

评论者:gshayban

补丁可能会对内联产生负面影响

0

评论者:alexmiller

的确,这有可能发生,尽管我认为在这种情况下可能很少。

0
参考: https://clojure.atlassian.net/browse/CLJ-2001(由 alex+import 报告)
...