[Math] ==~ operator applies to any <AlmostEquatable, EquatableWithinEpsilon>

This commit is contained in:
Eryn Wells 2015-11-06 23:21:49 -08:00
parent 1d1e5134d8
commit 58dfb3f787

View file

@ -9,19 +9,36 @@
import Foundation
public typealias Float = Swift.Float
public typealias Double = Swift.Double
/** Acceptable tolerance for Float equality. */
let Epsilon: Float = 1e-6
extension Float {
/** Test that `other` is almost equal (i.e. within the +/- Epsilon) to `self`. */
func almostEqual(other: Float) -> Bool {
return other >= (self - Epsilon) && other <= (self + Epsilon)
}
public protocol AlmostEquatable {
@warn_unused_result
func ==~(lhs: Self, rhs: Self) -> Bool
}
/** Custom operator for almost-equality of floats. */
infix operator =~ { associativity left precedence 130 }
public func =~(lhs: Float, rhs: Float) -> Bool {
return lhs.almostEqual(rhs)
public protocol EquatableWithinEpsilon: Strideable {
static var Epsilon: Self.Stride { get }
}
extension Float: EquatableWithinEpsilon {
public static let Epsilon: Float.Stride = 1e-8
}
extension Double: EquatableWithinEpsilon {
public static let Epsilon: Double.Stride = 1e-16
}
private func almostEqual<T: EquatableWithinEpsilon>(lhs: T, _ rhs: T, epsilon: T.Stride) -> Bool {
return abs(lhs - rhs) <= epsilon
}
/** Almost-equality of floating point types. */
infix operator ==~ { associativity left precedence 130 }
public func ==~<T: protocol<AlmostEquatable, EquatableWithinEpsilon>>(lhs: T, rhs: T) -> Bool {
return almostEqual(lhs, rhs, epsilon: T.Epsilon)
}
infix operator !==~ { associativity left precedence 130 }
public func !==~<T: AlmostEquatable>(lhs: T, rhs: T) -> Bool {
return !(lhs ==~ rhs)
}