isApproximatelyEqual(to:relativeTolerance:norm:)

Test if self and other are approximately equal.

ApproximateEquality.swift:75
func isApproximatelyEqual(to other: Self, relativeTolerance: Magnitude = Magnitude.ulpOfOne.squareRoot(), norm: (Self) -> Magnitude = \.magnitude) -> Bool

Parameters

other

The value to which self is compared.

relativeTolerance

The tolerance to use for the comparison. Defaults to .ulpOfOne.squareRoot().

This value should be non-negative and less than or equal to 1. This constraint on is only checked in debug builds, because a mathematically well-defined result exists for any tolerance, even one out of range.

norm

The norm to use for the comparison. Defaults to \.magnitude.

true if self and other are equal, or if they are finite and

norm(self - other) <= relativeTolerance * scale

where scale is

max(norm(self), norm(other), .leastNormalMagnitude)

The default value of relativeTolerance is .ulpOfOne.squareRoot(), which corresponds to expecting “about half the digits” in the computed results to be good. This is the usual guidance in numerical analysis, if you don’t know anything about the computation being performed, but is not suitable for all use cases.

Mathematical Properties:

  • isApproximatelyEqual(to:relativeTolerance:norm:) is reflexive for non-exceptional values (such as NaN).

  • isApproximatelyEqual(to:relativeTolerance:norm:) is symmetric.

  • isApproximatelyEqual(to:relativeTolerance:norm:) is not transitive. Because of this, approximately equality is not an equivalence relation, even when restricted to non-exceptional values.

    This means that you must not use approximate equality to implement a conformance to Equatable, as it will violate the invariants of code written against that protocol.

  • For any point a, the set of values that compare approximately equal to a is convex. (Under the assumption that the .magnitude property implements a valid norm.)

  • isApproximatelyEqual(to:relativeTolerance:norm:) is scale invariant, so long as no underflow or overflow has occured, and no exceptional value is produced by the scaling.

See Also:

  • isApproximatelyEqual(to:absoluteTolerance:[relativeTolerance:norm:])