@@ -22,9 +22,10 @@ extension Numeric where Magnitude: FloatingPoint {
22
22
/// ```
23
23
///
24
24
/// The default value of `relativeTolerance` is `.ulpOfOne.squareRoot()`,
25
- /// which corresponds to expecting "about half the digits" in the computed results to be good.
26
- /// This is the usual guidance in numerical analysis, if you don't know anything about the
27
- /// computation being performed, but is not suitable for all use cases.
25
+ /// which corresponds to expecting "about half the digits" in the computed
26
+ /// results to be good. This is the usual guidance in numerical analysis,
27
+ /// if you don't know anything about the computation being performed, but
28
+ /// is not suitable for all use cases.
28
29
///
29
30
/// Mathematical Properties:
30
31
/// ------------------------
@@ -34,16 +35,21 @@ extension Numeric where Magnitude: FloatingPoint {
34
35
///
35
36
/// - `isApproximatelyEqual(to:relativeTolerance:norm:)` is _symmetric_.
36
37
///
37
- /// - `isApproximatelyEqual(to:relativeTolerance:norm:)` is __not__ _transitive_.
38
- /// Because of this, approximately equality is __not an equivalence relation__,
39
- /// even when restricted to non-exceptional values.
38
+ /// - `isApproximatelyEqual(to:relativeTolerance:norm:)` is __not__
39
+ /// _transitive_. Because of this, approximately equality is __not an
40
+ /// equivalence relation__, even when restricted to non-exceptional values.
40
41
///
41
- /// - For any point `a`, the set of values that compare approximately equal to `a` is _convex_.
42
- /// (Under the assumption that the `.magnitude` property implements a valid norm.)
42
+ /// This means that you must not use approximate equality to implement
43
+ /// a conformance to Equatable, as it will violate the invariants of
44
+ /// code written against that protocol.
45
+ ///
46
+ /// - For any point `a`, the set of values that compare approximately equal
47
+ /// to `a` is _convex_. (Under the assumption that the `.magnitude`
48
+ /// property implements a valid norm.)
43
49
///
44
50
/// - `isApproximatelyEqual(to:relativeTolerance:norm:)` is _scale invariant_,
45
- /// so long as no underflow or overflow has occured, and no exceptional value is produced
46
- /// by the scaling.
51
+ /// so long as no underflow or overflow has occured, and no exceptional
52
+ /// value is produced by the scaling.
47
53
///
48
54
/// See Also:
49
55
/// -------
@@ -57,8 +63,9 @@ extension Numeric where Magnitude: FloatingPoint {
57
63
/// Defaults to `.ulpOfOne.squareRoot()`.
58
64
///
59
65
/// This value should be non-negative and less than or equal to 1.
60
- /// This constraint on is only checked in debug builds, because a mathematically
61
- /// well-defined result exists for any tolerance, even one out of range.
66
+ /// This constraint on is only checked in debug builds, because a
67
+ /// mathematically well-defined result exists for any tolerance,
68
+ /// even one out of range.
62
69
///
63
70
/// - norm: The [norm] to use for the comparison.
64
71
/// Defaults to `\.magnitude`.
@@ -99,13 +106,17 @@ extension Numeric where Magnitude: FloatingPoint {
99
106
/// - `isApproximatelyEqual(to:absoluteTolerance:relativeTolerance:)`
100
107
/// is _symmetric_.
101
108
///
102
- /// - `isApproximatelyEqual(to:absoluteTolerance: relativeTolerance:)`
103
- /// is __not__ _transitive_. Because of this, approximately equality is
104
- /// __not an equivalence relation__, even when restricted to non-exceptional values.
109
+ /// - `isApproximatelyEqual(to:relativeTolerance:norm:)` is __not__
110
+ /// _transitive_. Because of this, approximately equality is __not an
111
+ /// equivalence relation__, even when restricted to non-exceptional values.
105
112
///
106
- /// - For any point `a`, the set of values that compare approximately equal to `a` is _convex_.
107
- /// (Under the assumption that `norm` implements a valid norm, which cannot be checked
108
- /// by this function.)
113
+ /// This means that you must not use approximate equality to implement
114
+ /// a conformance to Equatable, as it will violate the invariants of
115
+ /// code written against that protocol.
116
+ ///
117
+ /// - For any point `a`, the set of values that compare approximately equal
118
+ /// to `a` is _convex_. (Under the assumption that `norm` implements a
119
+ /// valid norm, which cannot be checked by this function.)
109
120
///
110
121
/// See Also:
111
122
/// -------
@@ -118,15 +129,17 @@ extension Numeric where Magnitude: FloatingPoint {
118
129
/// - absoluteTolerance: The absolute tolerance to use in the comparison.
119
130
///
120
131
/// This value should be non-negative and finite.
121
- /// This constraint on is only checked in debug builds, because a mathematically
122
- /// well-defined result exists for any tolerance, even one out of range.
132
+ /// This constraint on is only checked in debug builds, because a
133
+ /// mathematically well-defined result exists for any tolerance,
134
+ /// even one out of range.
123
135
///
124
136
/// - relativeTolerance: The relative tolerance to use in the comparison.
125
137
/// Defaults to zero.
126
138
///
127
139
/// This value should be non-negative and less than or equal to 1.
128
- /// This constraint on is only checked in debug builds, because a mathematically
129
- /// well-defined result exists for any tolerance, even one out of range.
140
+ /// This constraint on is only checked in debug builds, because a
141
+ /// mathematically well-defined result exists for any tolerance,
142
+ /// even one out of range.
130
143
@inlinable @inline ( __always)
131
144
public func isApproximatelyEqual(
132
145
to other: Self ,
@@ -143,7 +156,8 @@ extension Numeric where Magnitude: FloatingPoint {
143
156
}
144
157
145
158
extension AdditiveArithmetic {
146
- /// Test if `self` and `other` are approximately equal with specified tolerances and norm.
159
+ /// Test if `self` and `other` are approximately equal with specified
160
+ /// tolerances and norm.
147
161
///
148
162
/// `true` if `self` and `other` are equal, or if they are finite and either
149
163
/// ```
@@ -166,11 +180,16 @@ extension AdditiveArithmetic {
166
180
///
167
181
/// - `isApproximatelyEqual(to:absoluteTolerance:relativeTolerance:norm:)`
168
182
/// is __not__ _transitive_. Because of this, approximately equality is
169
- /// __not an equivalence relation__, even when restricted to non-exceptional values.
183
+ /// __not an equivalence relation__, even when restricted to
184
+ /// non-exceptional values.
185
+ ///
186
+ /// This means that you must not use approximate equality to implement
187
+ /// a conformance to Equatable, as it will violate the invariants of
188
+ /// code written against that protocol.
170
189
///
171
- /// - For any point `a`, the set of values that compare approximately equal to `a` is _convex_.
172
- /// (Under the assumption that `norm` implements a valid norm, which cannot be checked
173
- /// by this function.)
190
+ /// - For any point `a`, the set of values that compare approximately equal
191
+ /// to `a` is _convex_ (under the assumption that `norm` implements a
192
+ /// valid norm, which cannot be checked by this function or a protocol).
174
193
///
175
194
/// See Also:
176
195
/// -------
@@ -184,30 +203,32 @@ extension AdditiveArithmetic {
184
203
/// - absoluteTolerance: The absolute tolerance to use in the comparison.
185
204
///
186
205
/// This value should be non-negative and finite.
187
- /// This constraint on is only checked in debug builds, because a mathematically
188
- /// well-defined result exists for any tolerance, even one out of range.
206
+ /// This constraint on is only checked in debug builds, because a
207
+ /// mathematically well-defined result exists for any tolerance, even
208
+ /// one out of range.
189
209
///
190
210
/// - relativeTolerance: The relative tolerance to use in the comparison.
191
211
/// Defaults to zero.
192
212
///
193
213
/// This value should be non-negative and less than or equal to 1.
194
- /// This constraint on is only checked in debug builds, because a mathematically
195
- /// well-defined result exists for any tolerance, even one out of range.
214
+ /// This constraint on is only checked in debug builds, because a
215
+ /// mathematically well-defined result exists for any tolerance,
216
+ /// even one out of range.
196
217
///
197
218
/// - norm: The norm to use for the comparison.
198
219
/// Defaults to `\.magnitude`.
199
220
///
200
- /// For example, if we wanted to test if a complex value was inside a circle of
201
- /// radius 0.001 centered at (1 + 0i), we could use:
221
+ /// For example, if we wanted to test if a complex value was inside a
222
+ /// circle of radius 0.001 centered at (1 + 0i), we could use:
202
223
/// ```
203
224
/// z.isApproximatelyEqual(
204
225
/// to: 1,
205
226
/// absoluteTolerance: 0.001,
206
227
/// norm: \.length
207
228
/// )
208
229
/// ```
209
- /// (if we used the default, we would be testing if `z` were inside a square region
210
- /// instead.)
230
+ /// (if we used the default norm, `.magnitude`, we would be testing if
231
+ /// `z` were inside a square region instead.)
211
232
@inlinable
212
233
public func isApproximatelyEqual< Magnitude> (
213
234
to other: Self ,
0 commit comments