9
9
//
10
10
//===----------------------------------------------------------------------===//
11
11
12
- /// Augmented arithmetic provides a family of algorithms that represent the
13
- /// results of floating-point computations using multiple values such that
14
- /// either the error is minimized or the result is exact.
15
12
public enum Augmented { }
16
13
17
14
extension Augmented {
@@ -53,6 +50,10 @@ extension Augmented {
53
50
54
51
/// The sum `a + b` represented as an implicit sum `head + tail`.
55
52
///
53
+ /// - Parameters:
54
+ /// - a: The summand with larger magnitude.
55
+ /// - b: The summand with smaller magnitude.
56
+ ///
56
57
/// `head` is the correctly rounded value of `a + b`. `tail` is the
57
58
/// error from that computation rounded to the closest representable
58
59
/// value.
@@ -62,15 +63,13 @@ extension Augmented {
62
63
///
63
64
/// This operation is sometimes called ["fastTwoSum"].
64
65
///
65
- /// - Parameters:
66
- /// - a: The summand with larger magnitude.
67
- /// - b: The summand with smaller magnitude.
68
- ///
69
- /// Preconditions:
70
- ///
71
- /// - `large.magnitude` must not be smaller than `small.magnitude`.
72
- /// They may be equal, or one or both may be `NaN`.
73
- /// This precondition is only enforced in debug builds.
66
+ /// > Note:
67
+ /// > `tail` is guaranteed to be the best approximation to the error of
68
+ /// the sum only if `large.magnitude` >= `small.magnitude`. If this is
69
+ /// not the case, then `head` is the correctly rounded sum, but `tail`
70
+ /// is not guaranteed to be the exact error. If you do not know a priori
71
+ /// how the magnitudes of `a` and `b` compare, you likely want to use
72
+ /// ``sum(_:_:)`` instead.
74
73
///
75
74
/// Edge Cases:
76
75
///
@@ -86,29 +85,23 @@ extension Augmented {
86
85
/// ["fastTwoSum"]: https://en.wikipedia.org/wiki/2Sum
87
86
@_transparent
88
87
public static func sum< T: Real > ( large a: T , small b: T ) -> ( head: T , tail: T ) {
89
- assert ( !( b. magnitude > a. magnitude) )
90
88
let head = a + b
91
89
let tail = a - head + b
92
90
return ( head, tail)
93
91
}
94
-
92
+
95
93
/// The sum `a + b` represented as an implicit sum `head + tail`.
96
94
///
97
95
/// `head` is the correctly rounded value of `a + b`. `tail` is the
98
96
/// error from that computation rounded to the closest representable
99
97
/// value.
100
98
///
101
- /// Unlike `Augmented.sum(large: a, small: b)`, the magnitude of the summands
102
- /// does not matter and `a.magnitude` might as well be strictly less than
103
- /// `b.magnitude`. However, it is recommended to only use this function over
104
- /// `Augmented.sum(large: a, small: b)` in cases where the ordering of the
105
- /// summands magnitude is unknown at compile time. In cases where either of
106
- /// the summands magnitude is guaranteed to be greater than or equal the
107
- /// magnitude of the other summand, use `Augmented.sum(large: a, small: b)`
108
- /// over this function; as it faster to calculate.
99
+ /// Unlike ``sum(large:small:)``, the magnitude of the summands does not
100
+ /// matter. If you know statically that `a.magnitude >= b.magnitude`, you
101
+ /// should use ``sum(large:small:)``. If you do not have such a static
102
+ /// bound, you should use this function instead.
109
103
///
110
- /// Unlike `Augmented.product(a, b)`, the rounding error of a sum can
111
- /// never underflow.
104
+ /// Unlike ``product(_:_:)``, the rounding error of a sum never underflows.
112
105
///
113
106
/// This operation is sometimes called ["twoSum"].
114
107
///
@@ -123,7 +116,7 @@ extension Augmented {
123
116
/// interpreted as having any meaning (it may be `NaN` or `infinity`).
124
117
///
125
118
/// Postconditions:
126
- ///
119
+ ///
127
120
/// - If `head` is normal, then `abs(tail) < head.ulp`.
128
121
/// Assuming IEEE 754 default rounding, `abs(tail) <= head.ulp/2`.
129
122
///
0 commit comments