Swift - 浮点值作为字典中的键?

Swift - Floating-point values as keys in a Dictionary?

是的,我已经做了研究,我能找到的最接近我的问题的页面是: this page 一点帮助也没有。

也就是说,Swift[中使用浮点值作为键是否安全(可靠)? =43=]字典?具体来说,CGFloat,Apple 文档说它实际上是 64 位系统上的 Double。

P.S。 (这很重要)- 我的 CGFloat 值将总是 以 .0 或 .5 作为小数部分结尾。示例 - 13、13.5、14、14.5 等。这会对此类字典查找的可靠性产生影响吗?

var dictionary: [CGFloat: MyObject] = [:]

...

// Could this type of lookup fail ?
if let mappedObject = dictionary[13.5] {
   ...
}

我有一个独特的用例,需要将某些对象映射到这些 CGFloat 值以便稍后快速查找。

根据我在单元测试中的经验,我知道 XCTAssertEqual 在比较两个浮点类型时有时会失败,而不使用“accuracy”参数。所以,我担心使用 CGFloats 作为键会导致后续查找失败,因为传入的键可能会偏离 0.0000000001 或类似的东西,因为浮点类型的底层表示。

谢谢。


编辑 -(感谢@Sweeper)是的,我确实考虑过使用 Int 键,通过使用以下转换将 CGFloat 转换为 Int:

intKey = Int(lroundf(Float(cgFloatKey * 2.0))

但是,我担心这个 ^ 转换(必须在每次查找时完成)需要足够的开销以使其不值得。

我在这里可能完全错了,也许这些操作快如闪电。任何人都可以评论每次执行查找时这种操作的效率吗?

您的担忧是有道理的,您知道 XCTAssertEqual 可能由于浮点值的工作方式而无法给​​出预期的结果,因此使用浮点值作为键与键查找所依赖的问题相同关于平等。

考虑另一种方式,比如使用合适的整数值作为键。

XCTAssertEqual 在比较浮点数据时不会失败。当且仅当参数不相等时,它才会生成失败,这是正确的行为。

如果参数不相等但如果用精确的数学计算本来会相等,这是因为在某些先前的操作中存在舍入误差,而不是在 XCTAssertEqual 中。对浮点数的担忧在于,对它们的算术运算和数学函数是对实际算术的近似,因此计算结果可能与精确数学所期望的理想结果不同。因此,不能使用 XCTAssertEqual 来确保使用近似值计算的两个结果相等,而实际上由于近似值它们可能不相等。其原因完全在于算术近似值,而不在于 XCTAssertEqual.

的行为

如果您的值的小数部分始终为 0 或 ½,则这些问题不适用(除非您的数字可能有很大偏差,例如生成 13½ 而不是 13)。因此,如果您的数字始终是您想要的精确值,则对算术近似值的担忧不适用,它们将适合用作字典键。