Skip to content

Commit acbf425

Browse files
committed
Remove precondition assert from Augmented.sum(large:small:)
This is potentially useful to identify some bugs, but there are also algorithms (notably Kahan summation) that can be written in terms of fast2sum but would fail this check. Rework documentation to account for the change.
1 parent af0352e commit acbf425

File tree

1 file changed

+18
-25
lines changed

1 file changed

+18
-25
lines changed

Sources/RealModule/AugmentedArithmetic.swift

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99
//
1010
//===----------------------------------------------------------------------===//
1111

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.
1512
public enum Augmented { }
1613

1714
extension Augmented {
@@ -53,6 +50,10 @@ extension Augmented {
5350

5451
/// The sum `a + b` represented as an implicit sum `head + tail`.
5552
///
53+
/// - Parameters:
54+
/// - a: The summand with larger magnitude.
55+
/// - b: The summand with smaller magnitude.
56+
///
5657
/// `head` is the correctly rounded value of `a + b`. `tail` is the
5758
/// error from that computation rounded to the closest representable
5859
/// value.
@@ -62,15 +63,13 @@ extension Augmented {
6263
///
6364
/// This operation is sometimes called ["fastTwoSum"].
6465
///
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.
7473
///
7574
/// Edge Cases:
7675
///
@@ -86,29 +85,23 @@ extension Augmented {
8685
/// ["fastTwoSum"]: https://en.wikipedia.org/wiki/2Sum
8786
@_transparent
8887
public static func sum<T:Real>(large a: T, small b: T) -> (head: T, tail: T) {
89-
assert(!(b.magnitude > a.magnitude))
9088
let head = a + b
9189
let tail = a - head + b
9290
return (head, tail)
9391
}
94-
92+
9593
/// The sum `a + b` represented as an implicit sum `head + tail`.
9694
///
9795
/// `head` is the correctly rounded value of `a + b`. `tail` is the
9896
/// error from that computation rounded to the closest representable
9997
/// value.
10098
///
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.
109103
///
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.
112105
///
113106
/// This operation is sometimes called ["twoSum"].
114107
///
@@ -123,7 +116,7 @@ extension Augmented {
123116
/// interpreted as having any meaning (it may be `NaN` or `infinity`).
124117
///
125118
/// Postconditions:
126-
///
119+
///
127120
/// - If `head` is normal, then `abs(tail) < head.ulp`.
128121
/// Assuming IEEE 754 default rounding, `abs(tail) <= head.ulp/2`.
129122
///

0 commit comments

Comments
 (0)