99//
1010//===----------------------------------------------------------------------===//
1111
12- /// The average of `a` and `b`, rounded to an integer according to `rule`.
13- ///
14- /// Unlike commonly seen expressions such as `(a+b)/2` or `(a+b) >> 1` or
15- /// `a + (b-a)/2` (all of which may overflow for fixed-width integers),
16- /// this function never overflows, and the result is guaranteed to be
17- /// representable in the result type.
18- ///
19- /// The default rounding rule is `.down`, which matches the behavior of
20- /// `(a + b) >> 1` when that expression does not overflow. Rounding
21- /// `.towardZero` matches the behavior of `(a + b)/2` when that expression
22- /// does not overflow. All other rounding modes are supported.
23- ///
24- /// Rounding `.down` is generally most efficient; if you do not have a
25- /// reason to chose a specific other rounding rule, you should use the
26- /// default.
27- @inlinable
28- public func midpoint< T: BinaryInteger > (
29- _ a: T ,
30- _ b: T ,
31- rounding rule: RoundingRule = . down
32- ) -> T {
33- // Isolate bits in a + b with weight 2, and those with weight 1.
34- let twos = a & b
35- let ones = a ^ b
36- let floor = twos + ones >> 1
37- let frac = ones & 1
38- switch rule {
39- case . down:
40- return floor
41- case . up:
42- return floor + frac
43- case . towardZero:
44- return floor + ( floor < 0 ? frac : 0 )
45- case . toNearestOrAwayFromZero:
46- fallthrough
47- case . awayFromZero:
48- return floor + ( floor >= 0 ? frac : 0 )
49- case . toNearestOrEven:
50- return floor + ( floor & frac)
51- case . toOdd:
52- return floor + ( ~ floor & frac)
53- case . stochastically:
54- return floor + ( Bool . random ( ) ? frac : 0 )
55- case . requireExact:
56- precondition ( frac == 0 )
57- return floor
58- }
59- }
60-
6112/// The average of `a` and `b`, rounded to an integer according to `rule`.
6213///
6314/// Unlike commonly seen expressions such as `(a+b)/2` or `(a+b) >> 1` or
@@ -84,13 +35,19 @@ public func midpoint<T: FixedWidthInteger>(
8435 let floor = twos &+ ones >> 1
8536 let frac = ones & 1
8637 switch rule {
38+ case . toNearestOrDown:
39+ fallthrough
8740 case . down:
8841 return floor
42+ case . toNearestOrUp:
43+ fallthrough
8944 case . up:
9045 return floor &+ frac
46+ case . toNearestOrZero:
47+ fallthrough
9148 case . towardZero:
9249 return floor &+ ( floor < 0 ? frac : 0 )
93- case . toNearestOrAwayFromZero :
50+ case . toNearestOrAway :
9451 fallthrough
9552 case . awayFromZero:
9653 return floor &+ ( floor >= 0 ? frac : 0 )
@@ -105,4 +62,3 @@ public func midpoint<T: FixedWidthInteger>(
10562 return floor
10663 }
10764}
108-
0 commit comments