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 一致。unchecked-long 将给出预期的结果,可能是这里的更好选择。因此,我们可能应该不应用此补丁而什么也不做。如果我们继续推进补丁,我们也可能想要在同一地点应用调用 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 报告)
...