isApproximatelyEqual(to:absoluteTolerance:relativeTolerance:norm:)

Test if self and other are approximately equal with specified tolerances and norm.

ApproximateEquality.swift:233
func isApproximatelyEqual<Magnitude>(to other: Self, absoluteTolerance: Magnitude, relativeTolerance: Magnitude = 0, norm: (Self) -> Magnitude) -> Bool where Magnitude : FloatingPoint

Parameters

other

The value to which self is compared.

absoluteTolerance

The absolute tolerance to use in the comparison.

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

relativeTolerance

The relative tolerance to use in the comparison. Defaults to zero.

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.

For example, if we wanted to test if a complex value was inside a circle of radius 0.001 centered at (1 + 0i), we could use:

z.isApproximatelyEqual(
  to: 1,
  absoluteTolerance: 0.001,
  norm: \.length
)

(if we used the default norm, .magnitude, we would be testing if z were inside a square region instead.)

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

norm(self - other) <= absoluteTolerance

or

norm(self - other) <= relativeTolerance * scale

where scale is max(norm(self), norm(other)).

Mathematical Properties:

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

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

  • isApproximatelyEqual(to:absoluteTolerance: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 norm implements a valid norm, which cannot be checked by this function or a protocol).

See Also:

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

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