@@ -14,15 +14,24 @@ extension BinaryInteger {
1414 ///
1515 /// The default rounding rule is `.down`, which _is not the same_ as the
1616 /// behavior of the `/` operator from the Swift standard library, but is
17- /// chosen because it generally produces a more useful remainder. To
18- /// match the behavior of `/`, use the `.towardZero` rounding mode.
17+ /// chosen because it generally produces a more useful remainder. In
18+ /// particular, when `b` is positive, the remainder is always positive.
19+ /// To match the behavior of `/`, use the `.towardZero` rounding mode.
20+ ///
21+ /// Note that the remainder of division is not always representable in an
22+ /// unsigned type if a rounding rule other than `.down`, `.towardZero`, or
23+ /// `.requireExact` is used. For example:
1924 ///
20- /// Be aware that if the type is unsigned, the remainder of the division
21- /// may not be representable when a non-default rounding mode is used:
22- /// ```
25+ /// let a: UInt = 5
26+ /// let b: UInt = 3
27+ /// let q = a.divided(by: b, rounding: .up) // 2
28+ /// let r = a - b*q // 5 - 3*2 overflows UInt.
2329 ///
24- /// ```
25- /// For signed types, the remainder is always representable.
30+ /// For this reason, there is no `remainder(dividingBy:rounding:)`
31+ /// operation defined on `BinaryInteger`. Signed integers do not have
32+ /// this problem, so it is defined on the `SignedInteger` protocol
33+ /// instead, as is an overload of `divided(by:rounding:)` that returns
34+ /// both quotient and remainder.
2635 @inlinable
2736 public func divided(
2837 by other: Self ,
@@ -120,6 +129,10 @@ extension BinaryInteger {
120129 // TODO: make this API and make it possible to implement more
121130 // efficiently. Customization point on new/revised integer
122131 // protocol? Shouldn't have to go through .words.
132+ /// The index of the most-significant set bit.
133+ ///
134+ /// - Precondition: self is assumed to be non-zero (to be changed
135+ /// if/when this becomes API).
123136 @usableFromInline
124137 internal var _msb : Int {
125138 // a == 0 is never used for division, because this is called
@@ -137,17 +150,21 @@ extension BinaryInteger {
137150
138151extension SignedInteger {
139152 /// Divides `self` by `other`, rounding the quotient according to `rule`,
140- /// and returns both the remainder.
153+ /// and returns the remainder.
141154 ///
142155 /// The default rounding rule is `.down`, which _is not the same_ as the
143156 /// behavior of the `%` operator from the Swift standard library, but is
144157 /// chosen because it generally produces a more useful remainder. To
145158 /// match the behavior of `%`, use the `.towardZero` rounding mode.
159+ ///
160+ /// - Precondition: `other` cannot be zero.
146161 @inlinable
147162 public func remainder(
148163 dividingBy other: Self ,
149164 rounding rule: RoundingRule = . down
150165 ) -> Self {
166+ // Produce correct remainder for the .min/-1 case, rather than trapping.
167+ if other == - 1 { return 0 }
151168 return self . divided ( by: other, rounding: rule) . remainder
152169 }
153170
@@ -163,7 +180,16 @@ extension SignedInteger {
163180 /// library, this function is a disfavored overload of `divided(by:)`
164181 /// instead of using the name `quotientAndRemainder(dividingBy:)`, which
165182 /// would shadow the standard library operation and change the behavior
166- /// of any existing use sites.
183+ /// of any existing use sites. To call this method, you must explicitly
184+ /// bind the result to a tuple:
185+ ///
186+ /// // This calls BinaryInteger's method, which returns only
187+ /// // the quotient.
188+ /// let result = 5.divided(by: 3, rounding: .up) // 2
189+ ///
190+ /// // This calls SignedInteger's method, which returns both
191+ /// // the quotient and remainder.
192+ /// let (q, r) = 5.divided(by: 3, rounding: .up) // (q = 2, r = -1)
167193 @inlinable @inline ( __always) @_disfavoredOverload
168194 public func divided(
169195 by other: Self ,
@@ -261,21 +287,28 @@ extension SignedInteger {
261287
262288/// `a = quotient*b + remainder`, with `remainder >= 0`.
263289///
290+ /// When `a` and `b` are both positive, `quotient` is `a/b` and `remainder`
291+ /// is `a%b`.
292+ ///
264293/// Rounding the quotient so that the remainder is non-negative is called
265294/// "Euclidean division". This is not a _rounding rule_, as `quotient`
266- /// cannot be determined just from the unrounded value `a/b`; we need to
267- /// also know the sign of either `a` or `b` to know which way to round.
268- /// Because of this, is not present in the `RoundingRule` enum and uses
269- /// a separate API from the other division operations.
295+ /// cannot be determined from the unrounded value `a/b`; we need to also
296+ /// know the sign of `a` or `b` or `r` to know which way to round. Because
297+ /// of this, is not present in the `RoundingRule` enum and uses a separate
298+ /// API from the other division operations.
270299///
271300/// - Parameters:
272301/// - a: The dividend
273- /// - b: The divisor, must be non-zero.
302+ /// - b: The divisor
303+ ///
304+ /// - Precondition: `b` must be non-zero, and the quotient `a/b` must be
305+ /// representable. In particular, if `T` is a signed fixed-width integer
306+ /// type, then `euclideanDivision(T.min, -1)` will trap, because `-T.min`
307+ /// is not representable.
274308///
275- /// - Returns: `(quotient, remainder)`, with `0 <= remainder < b.magnitude`
276- /// if `quotient` is representable.
309+ /// - Returns: `(quotient, remainder)`, with `0 <= remainder < b.magnitude`.
277310func euclideanDivision< T> ( _ a: T , _ b: T ) -> ( quotient: T , remainder: T )
278311where T: SignedInteger
279312{
280- a. divided ( by: b, rounding: b >= 0 ? . down : . up )
313+ a. divided ( by: b, rounding: a >= 0 ? . towardZero : . awayFromZero )
281314}
0 commit comments