请在2024年Clojure状态调查中分享您的看法!

欢迎!请参阅关于页面了解更多此功能的信息。

0
Java Interop

在从map中获取浮点数值时,如果map中包含超过8个值,则找不到该值。

例如

(get {1.0 "a" 2.0 "b" 3.0 "c" 4.0 "d" 5.0 "e" 6.0 "f" 7.0 "g" 8.0 "h" 1 "i"} (float 1)) => nil
(get {1.0 "a" 2.0 "b" 3.0 "c" 4.0 "d" 5.0 "e" 6.0 "f" 7.0 "g" 8.0 "h"} (float 1)) => "a"

5 个答案

0

评论者:ashercoren

问题不仅存在于map中。

以下是一个Set的示例
(contains? #{1.0 1.1} (float 1)) => true
(contains? #{1.0 1.1 1.2} (float 1)) => false

0

评论者:jafingerhut

我认为在最多8个键的map中查找float值只是实现上的一个意外。

在更大的map和hash set中使用时会失败,因为在(double 1.0)和(float 1.0)中有不同的哈希值。

user=> (hash (float 1.0)) 1065353216 user=> (hash 1.0) 1072693248

您的示例中所有如1.0等其他值都默认为double类型。注意,如果您强制map的键为float,即使map有超过8个键,查找也会成功

user=> (get {(float 1.0) "a" 2.0 "b" 3.0 "c" 4.0 "d" 5.0 "e" 6.0 "f" 7.0 "g" 8.0 "h" 1 "i"} (float 1)) "a"

我猜测这里的除了使用小map的get操作意外返回了成功的查找之外,其他一切都是按设计工作的。

我认为使用小地图查找时能够找到匹配项(float 1)的原因可能是小地图的实现是作为一个ArrayMap,其中查找键会依次与数组中的所有键进行比较,使用clojure.core/=(或其Java等价物)进行比较,并且

用户=> (= (float 1) (double 1)) 真的

0

评论者:jafingerhut

附加说明:CLJ-1649 是由希望浮点数和双精度浮点数应该具有一致的哈希和等式的人创建的。你可以在该票证的描述中了解更多信息。尚未作出判断表示此类更改是否会在Clojure中实施,但如果Rich关于票证CLJ-1036的评论有任何迹象,似乎不太可能更改。

一般建议:如果可能避免的话,不要在Clojure代码中混合浮点数和双精度浮点数。

0

评论者:ashercoren

感谢 @Andy!

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