@@ -14,15 +14,24 @@ extension BinaryInteger {
14
14
///
15
15
/// The default rounding rule is `.down`, which _is not the same_ as the
16
16
/// 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:
19
24
///
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.
23
29
///
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.
26
35
@inlinable
27
36
public func divided(
28
37
by other: Self ,
@@ -120,6 +129,10 @@ extension BinaryInteger {
120
129
// TODO: make this API and make it possible to implement more
121
130
// efficiently. Customization point on new/revised integer
122
131
// 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).
123
136
@usableFromInline
124
137
internal var _msb : Int {
125
138
// a == 0 is never used for division, because this is called
@@ -137,17 +150,21 @@ extension BinaryInteger {
137
150
138
151
extension SignedInteger {
139
152
/// Divides `self` by `other`, rounding the quotient according to `rule`,
140
- /// and returns both the remainder.
153
+ /// and returns the remainder.
141
154
///
142
155
/// The default rounding rule is `.down`, which _is not the same_ as the
143
156
/// behavior of the `%` operator from the Swift standard library, but is
144
157
/// chosen because it generally produces a more useful remainder. To
145
158
/// match the behavior of `%`, use the `.towardZero` rounding mode.
159
+ ///
160
+ /// - Precondition: `other` cannot be zero.
146
161
@inlinable
147
162
public func remainder(
148
163
dividingBy other: Self ,
149
164
rounding rule: RoundingRule = . down
150
165
) -> Self {
166
+ // Produce correct remainder for the .min/-1 case, rather than trapping.
167
+ if other == - 1 { return 0 }
151
168
return self . divided ( by: other, rounding: rule) . remainder
152
169
}
153
170
@@ -163,7 +180,16 @@ extension SignedInteger {
163
180
/// library, this function is a disfavored overload of `divided(by:)`
164
181
/// instead of using the name `quotientAndRemainder(dividingBy:)`, which
165
182
/// 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)
167
193
@inlinable @inline ( __always) @_disfavoredOverload
168
194
public func divided(
169
195
by other: Self ,
@@ -261,21 +287,28 @@ extension SignedInteger {
261
287
262
288
/// `a = quotient*b + remainder`, with `remainder >= 0`.
263
289
///
290
+ /// When `a` and `b` are both positive, `quotient` is `a/b` and `remainder`
291
+ /// is `a%b`.
292
+ ///
264
293
/// Rounding the quotient so that the remainder is non-negative is called
265
294
/// "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.
270
299
///
271
300
/// - Parameters:
272
301
/// - 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.
274
308
///
275
- /// - Returns: `(quotient, remainder)`, with `0 <= remainder < b.magnitude`
276
- /// if `quotient` is representable.
309
+ /// - Returns: `(quotient, remainder)`, with `0 <= remainder < b.magnitude`.
277
310
func euclideanDivision< T> ( _ a: T , _ b: T ) -> ( quotient: T , remainder: T )
278
311
where T: SignedInteger
279
312
{
280
- a. divided ( by: b, rounding: b >= 0 ? . down : . up )
313
+ a. divided ( by: b, rounding: a >= 0 ? . towardZero : . awayFromZero )
281
314
}
0 commit comments