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 值的额外类型转换测试。未检查的长类型转换似乎不受影响(返回的值没有变化)。

问题: 尽管可能令人困惑,但错误的结果可能实际上是与 Java 一致的。未经检查的长类型转换将给出预期的结果,并且可能是这里的更好选择。所以,我们可能不应该应用此补丁,而应什么都不做。如果我们继续应用补丁,我们可能还可以将等效更改应用到调用 byteValueExact(),shortValueExact(),intValueExact() 和 toBigIntegerExact() 的适当位置。

补丁: clj-2001.patch

4 个答案

0

由 alexmiller 发布的评论

是的,RT.longCast() 似乎没有明确处理 BigDecimal。

0
by

评论由:gshayban

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

0
by

由 alexmiller 发布的评论

确实有可能,尽管我认为在这个情况下可能很罕见。

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