2
2
//
3
3
// This source file is part of the Swift Numerics open source project
4
4
//
5
- // Copyright (c) 2020 Apple Inc. and the Swift Numerics project authors
5
+ // Copyright (c) 2020-2021 Apple Inc. and the Swift Numerics project authors
6
6
// Licensed under Apache License v2.0 with Runtime Library Exception
7
7
//
8
8
// See https://swift.org/LICENSE.txt for license information
@@ -64,7 +64,7 @@ extension Augmented {
64
64
/// never underflow. However, it may not be exactly representable when
65
65
/// `a` and `b` differ widely in magnitude.
66
66
///
67
- /// This operation is sometimes called "fastTwoSum".
67
+ /// This operation is sometimes called [ "fastTwoSum"] .
68
68
///
69
69
/// - Parameters:
70
70
/// - a: The summand with larger magnitude.
@@ -86,11 +86,59 @@ extension Augmented {
86
86
/// -
87
87
/// - If `head` is normal, then `abs(tail) < head.ulp`.
88
88
/// Assuming IEEE 754 default rounding, `abs(tail) <= head.ulp/2`.
89
+ ///
90
+ /// ["fastTwoSum"]: https://en.wikipedia.org/wiki/2Sum
89
91
@_transparent
90
92
public static func sum< T: Real > ( large a: T , small b: T ) -> ( head: T , tail: T ) {
91
93
assert ( !( b. magnitude > a. magnitude) )
92
94
let head = a + b
93
95
let tail = a - head + b
94
96
return ( head, tail)
95
97
}
98
+
99
+ /// The sum `a + b` represented as an implicit sum `head + tail`.
100
+ ///
101
+ /// `head` is the correctly rounded value of `a + b`. `tail` is the
102
+ /// error from that computation rounded to the closest representable
103
+ /// value.
104
+ ///
105
+ /// Unlike `Augmented.sum(large: a, small: b)`, the magnitude of the summands
106
+ /// does not matter and `a.magnitude` might as well be strictly less than
107
+ /// `b.magnitude`. However, it is recommended to only use this function over
108
+ /// `Augmented.sum(large: a, small: b)` in cases where the ordering of the
109
+ /// summands magnitude is unknown at compile time. In cases where either of
110
+ /// the summands magnitude is guaranteed to be greater than or equal the
111
+ /// magnitude of the other summand, use `Augmented.sum(large: a, small: b)`
112
+ /// over this function; as it faster to calculate.
113
+ ///
114
+ /// Unlike `Augmented.product(a, b)`, the rounding error of a sum can
115
+ /// never underflow. However, it may not be exactly representable when
116
+ /// `a` and `b` differ widely in magnitude.
117
+ ///
118
+ /// This operation is sometimes called ["twoSum"].
119
+ ///
120
+ /// - Parameters:
121
+ /// - a: One of the summand
122
+ /// - b: The other summand
123
+ ///
124
+ /// Edge Cases:
125
+ /// -
126
+ /// - `head` is always the IEEE 754 sum `a + b`.
127
+ /// - If `head` is not finite, `tail` is unspecified and should not be
128
+ /// interpreted as having any meaning (it may be `NaN` or `infinity`).
129
+ ///
130
+ /// Postconditions:
131
+ /// -
132
+ /// - If `head` is normal, then `abs(tail) < head.ulp`.
133
+ /// Assuming IEEE 754 default rounding, `abs(tail) <= head.ulp/2`.
134
+ ///
135
+ /// ["twoSum"]: https://en.wikipedia.org/wiki/2Sum
136
+ @_transparent
137
+ public static func sum< T: Real > ( _ a: T , _ b: T ) -> ( head: T , tail: T ) {
138
+ let head = a + b
139
+ let x = head - b
140
+ let y = head - x
141
+ let tail = ( a - x) + ( b - y)
142
+ return ( head, tail)
143
+ }
96
144
}
0 commit comments