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

欢迎!请参阅关于页面以获取有关如何工作的更多信息。

0
Java互操作

当在一个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中查找浮点数的实现是一种意外。

大型map和哈希集合失败的的原因是(double 1.0)和(float 1.0)的哈希值不同。

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

您示例中的所有类似1.0等的值都默认为double类型。注意,如果您强制map的键为浮点数,则在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发生意外成功外,这里的工作都是按照设计的。

我相信在使用小地图进行查找时能找到一个匹配(浮点数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报告)
...