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

欢迎!请查阅关于页面,了解更多关于该功能的信息。

0
Java 交互

当获取映射中浮点数的值时,如果映射包含超过 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 个键的映射中查找浮点值是一种实现上的意外。

之所以在大映射和哈希集中失败,是因为双精度浮点数(double 1.0)和单精度浮点数(float 1.0)的哈希值不同。

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

所有如 1.0 这样的值默认为双精度类型。请注意,如果您强制将映射的键设置为浮点类型,即使在映射有超过 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"

我的猜测是,除了一小部分映射意外地返回成功查找外,这里的工作都是按照设计进行的。

我认为使用小型地图(ArrayMap实现)查找时找不到(float 1)匹配的原因可能是因为小型地图的实现将查找键与数组中所有键顺序比较,使用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 报告)
...