22//
33// This source file is part of the Swift Numerics open source project
44//
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
66// Licensed under Apache License v2.0 with Runtime Library Exception
77//
88// See https://swift.org/LICENSE.txt for license information
@@ -64,7 +64,7 @@ extension Augmented {
6464 /// never underflow. However, it may not be exactly representable when
6565 /// `a` and `b` differ widely in magnitude.
6666 ///
67- /// This operation is sometimes called "fastTwoSum".
67+ /// This operation is sometimes called [ "fastTwoSum"] .
6868 ///
6969 /// - Parameters:
7070 /// - a: The summand with larger magnitude.
@@ -86,11 +86,59 @@ extension Augmented {
8686 /// -
8787 /// - If `head` is normal, then `abs(tail) < head.ulp`.
8888 /// Assuming IEEE 754 default rounding, `abs(tail) <= head.ulp/2`.
89+ ///
90+ /// ["fastTwoSum"]: https://en.wikipedia.org/wiki/2Sum
8991 @_transparent
9092 public static func sum< T: Real > ( large a: T , small b: T ) -> ( head: T , tail: T ) {
9193 assert ( !( b. magnitude > a. magnitude) )
9294 let head = a + b
9395 let tail = a - head + b
9496 return ( head, tail)
9597 }
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+ }
96144}
0 commit comments