我试图比较两个相同的纬度,它是类型的Double,当我打印结果时,它被评估为false.
print("spot latitude: " + String(spot.location.latitude))
print("first object: " + String(firstSpot.location.latitude))
print(spot.location.latitude == firstSpot.location.latitude)
Run Code Online (Sandbox Code Playgroud)
输出:
spot latitude: 32.8842183049047
first object: 32.8842183049047
false
Run Code Online (Sandbox Code Playgroud)
任何人都知道发生了什么?
And*_*rea 11
比较双打中的平等很少给你预期的答案,这是由于如何存储双打.您可以创建自定义运算符,请记住您应该使用一些准确性.
要了解更多信息,您可以查看此答案,即使它说的是ObjC,原则也是超级有效的.
由于我在线检查有同样的问题,我在apple dev论坛上找到了这个答案.
这个功能应该可以做到,你可以轻松创建一个自定义运算符:
func doubleEqual(_ a: Double, _ b: Double) -> Bool {
return fabs(a - b) < Double.ulpOfOne
}
Run Code Online (Sandbox Code Playgroud)
我试图从swift 2.x转换为3.x似乎宏DBL_EPSILON不再可用了.
使用==比较double或float值将不会在大多数编程语言中给出预期结果,这意味着您认为应该相等的数字实际上略有不同.相反,如果差值低于某个阈值,则计算绝对差值并将数字处理为相等.有关更多说明,请参阅使用epsilon将double比较为零.
四舍五入的解决方案可能是获得接近值的最佳选择:
extension Double {
static func equal(_ lhs: Double, _ rhs: Double, precise value: Int? = nil) -> Bool {
guard let value = value else {
return lhs == rhs
}
return lhs.precised(value) == rhs.precised(value)
}
func precised(_ value: Int = 1) -> Double {
let offset = pow(10, Double(value))
return (self * offset).rounded() / offset
}
}
// values retrieving
a: 64.3465535142464, b: 64.3465535142464
// values debug description
a: 64.346553514246409, b: 64.346553514246395
// calculations
a == b // false
a.precised(10) == b.precised(10) // true
// or
Double.equal(a, b) // false
Double.equal(a, b, precise: 10) // true
Run Code Online (Sandbox Code Playgroud)
如果使用带有 epsilon 的修正,无论如何我都会得到假等于双打:
// values retrieving
a: 64.3465535142464, b: 64.3465535142464
// values debug description
a: 64.346553514246409, b: 64.346553514246395
// calculations
a == b // false
a - b // 1.4210854715202e-14
a - b < .ulpOfOne // false
Run Code Online (Sandbox Code Playgroud)
您可以使用此扩展
extension FloatingPoint {
func isNearlyEqual(to value: Self) -> Bool {
return abs(self - value) <= .ulpOfOne
}
}
Run Code Online (Sandbox Code Playgroud)
或根据本指南
extension FloatingPoint {
func isNearlyEqual(to value: Self) -> Bool {
let absA = abs(self)
let absB = abs(value);
let diff = abs(self - value);
if self == value { // shortcut, handles infinities
return true
} else if self == .zero || value == .zero || (absA + absB) < Self.leastNormalMagnitude {
// a or b is zero or both are extremely close to it
// relative error is less meaningful here
return diff < Self.ulpOfOne * Self.leastNormalMagnitude
} else { // use relative error
return diff / min((absA + absB), Self.greatestFiniteMagnitude) < .ulpOfOne;
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6841 次 |
| 最近记录: |