Merging different Swift 4
technics together:
import Foundation
infix operator ~==
infix operator ~<=
infix operator ~>=
extension Double {
static func ~== (lhs: Double, rhs: Double) -> Bool {
// If we add even a single zero more,
// our Decimal test would fail.
fabs(lhs - rhs) < 0.000000000001
}
static func ~<= (lhs: Double, rhs: Double) -> Bool {
(lhs < rhs) || (lhs ~== rhs)
}
static func ~>= (lhs: Double, rhs: Double) -> Bool {
(lhs > rhs) || (lhs ~== rhs)
}
}
Usage:
// Check if two double variables are almost equal:
if a ~== b {
print("was nearly equal!")
}
Note that ~<=
is the fuzzy-compare version of less-than (<=
) operator,
And ~>=
is the fuzzy-compare greater-than (>=
) operator.
Also, originally I was using Double.ulpOfOne
, but changed to a constant (to be even more fuzzy).
Finally, as mentioned on my profile, usage under Apache 2.0
license is allowed as well (without attribution need).
Testing
import Foundation
import XCTest
@testable import MyApp
class MathTest: XCTestCase {
func testFuzzyCompare_isConstantBigEnough() {
// Dummy.
let decimal: Decimal = 3062.36
let double: Double = 3062.36
// With casting up from low-precession type.
let doubleCasted: Double = NSDecimalNumber(decimal: decimal).doubleValue
// Actual test.
XCTAssertEqual(decimal, Decimal(doubleCasted));
XCTAssertNotEqual(double, doubleCasted);
XCTAssertTrue(double ~== doubleCasted);
}
func testDouble_correctConstant() {
XCTAssertEqual(Double.ulpOfOne, 2.220446049250313e-16)
}
}