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发表的评论:

我认为在map中使用最多8个键对float的get查找不过是实现的意外。

它在大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)) true

0

由jafingerhut发表的评论:

附加说明:CLJ-1649是由某人创建的,希望浮点数和双精度数在散列和=上应该与彼此保持一致。您可以在该票务描述中了解更多信息。尚未作出是否会在Clojure中作出此类更改的判断,但据Rich在票务CLJ-1036上的评论来看,似乎不太可能更改。

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

0

由ashercoren发表的评论:

感谢 @Andy!

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