请在2024年Clojure调查问卷中分享您的想法!

欢迎!请查看关于页面以了解更多关于如何使用本网站的信息。

0
Java Interop

当在映射中获取浮点数的值时,如果映射包含超过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 提供

这个问题不仅与映射有关。

以下是一个使用集合的例子
(contains? #{1.0 1.1} (float 1)) => true
(contains? #{1.0 1.1 1.2} (float 1)) => false

0

评论由:jafingerhut 提供

我相信在具有最多8个键的映射中对浮点数的get查找失败是实施中的意外。

它在大映射和散列集中失败的原因是(double 1.0)和(float 1.0)的哈希值不同。

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

您的例子中的所有值(例如1.0等)默认为double类型。请注意,如果您强制将映射的键的类型设置为float,则即使在映射有超过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"

我的猜想是,除了小映射上的get操作意外地返回成功查找之外,所有这些都是按设计正常工作的。

我认为使用小地图查找匹配项(浮点数1)没有找到的原因可能是因为小地图的实现作为一个ArrayMap,使用clojure.core/=(或其Java等价函数)顺序比较所有键与数组中的键,并且

user=> (= (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报告)
...