@@ -149,7 +149,7 @@ extension _${U}Int128: Numeric {
149
149
150
150
// Is 'source' entirely representable in Low?
151
151
if let low = Low(exactly: source.magnitude) {
152
- self.init(source._isNegative ? (~0, ~ low &+ 1 ) : (0, low))
152
+ self.init(source._isNegative ? (~0, low._twosComplement ) : (0, low))
153
153
} else {
154
154
// At this point we know source.bitWidth > High.bitWidth, or else we
155
155
// would've taken the first branch.
@@ -260,7 +260,7 @@ extension _${U}Int128: FixedWidthInteger {
260
260
let isNegative = (self._isNegative != rhs._isNegative)
261
261
let (p, overflow) = self.magnitude.multipliedReportingOverflow(
262
262
by: rhs.magnitude)
263
- let r = _Int128(bitPattern: isNegative ? ~(p &- .one) : p)
263
+ let r = _Int128(bitPattern: isNegative ? p._twosComplement : p)
264
264
return (r, overflow || (isNegative != r._isNegative))
265
265
% else:
266
266
let h1 = self.high.multipliedReportingOverflow(by: rhs.low)
@@ -275,6 +275,31 @@ extension _${U}Int128: FixedWidthInteger {
275
275
% end
276
276
}
277
277
278
+ /// Returns the product of this value and the given 64-bit value, along with a
279
+ /// Boolean value indicating whether overflow occurred in the operation.
280
+ internal func multipliedReportingOverflow(
281
+ by other: UInt64
282
+ ) -> (partialValue: Self, overflow: Bool) {
283
+ % if signed:
284
+ let isNegative = self._isNegative
285
+ let (p, overflow) = self.magnitude.multipliedReportingOverflow(by: other)
286
+ let r = _Int128(bitPattern: isNegative ? p._twosComplement : p)
287
+ return (r, overflow || (isNegative != r._isNegative))
288
+ % else:
289
+ let h1 = self.high.multipliedReportingOverflow(by: other)
290
+ let (h2, l) = self.low.multipliedFullWidth(by: other)
291
+ let high = h1.partialValue.addingReportingOverflow(h2)
292
+ let overflow = h1.overflow || high.overflow
293
+ return (Self(high: high.partialValue, low: l), overflow)
294
+ % end
295
+ }
296
+
297
+ internal func multiplied(by other: UInt64) -> Self {
298
+ let r = multipliedReportingOverflow(by: other)
299
+ _precondition(!r.overflow, "Overflow in multiplication")
300
+ return r.partialValue
301
+ }
302
+
278
303
internal func quotientAndRemainder(
279
304
dividingBy other: Self
280
305
) -> (quotient: Self, remainder: Self) {
@@ -515,6 +540,13 @@ extension BinaryInteger {
515
540
fileprivate var _isNegative: Bool { self < Self.zero }
516
541
}
517
542
543
+ extension FixedWidthInteger {
544
+ @inline(__always)
545
+ fileprivate var _twosComplement: Self {
546
+ ~self &+ 1
547
+ }
548
+ }
549
+
518
550
private typealias _Wide2<F: FixedWidthInteger> =
519
551
(high: F, low: F.Magnitude)
520
552
0 commit comments