diff --git a/Math/Math/Types.swift b/Math/Math/Types.swift index 374e300..37f4b88 100644 --- a/Math/Math/Types.swift +++ b/Math/Math/Types.swift @@ -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(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 ==~>(lhs: T, rhs: T) -> Bool { + return almostEqual(lhs, rhs, epsilon: T.Epsilon) +} + +infix operator !==~ { associativity left precedence 130 } +public func !==~(lhs: T, rhs: T) -> Bool { + return !(lhs ==~ rhs) } \ No newline at end of file