Skip to content

Instantly share code, notes, and snippets.

@erynofwales
Created November 7, 2015 07:14
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save erynofwales/513d3849be997c51ca0b to your computer and use it in GitHub Desktop.
Save erynofwales/513d3849be997c51ca0b to your computer and use it in GitHub Desktop.
An AlmostEquatable protocol for Swift floating point types
import Foundation
public protocol AlmostEquatable {
@warn_unused_result
func ==~(lhs: Self, rhs: Self) -> Bool
}
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)
}
/** Inverse almost-equality for any AlmostEquatable. */
infix operator !==~ { associativity left precedence 130 }
public func !==~<T: AlmostEquatable>(lhs: T, rhs: T) -> Bool {
return !(lhs ==~ rhs)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment