@@ -149,7 +149,7 @@ extension _${U}Int128: Numeric {
149149
150150 // Is 'source' entirely representable in Low?
151151 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))
153153 } else {
154154 // At this point we know source.bitWidth > High.bitWidth, or else we
155155 // would've taken the first branch.
@@ -260,7 +260,7 @@ extension _${U}Int128: FixedWidthInteger {
260260 let isNegative = (self._isNegative != rhs._isNegative)
261261 let (p, overflow) = self.magnitude.multipliedReportingOverflow(
262262 by: rhs.magnitude)
263- let r = _Int128(bitPattern: isNegative ? ~(p &- .one) : p)
263+ let r = _Int128(bitPattern: isNegative ? p._twosComplement : p)
264264 return (r, overflow || (isNegative != r._isNegative))
265265 % else:
266266 let h1 = self.high.multipliedReportingOverflow(by: rhs.low)
@@ -275,6 +275,31 @@ extension _${U}Int128: FixedWidthInteger {
275275 % end
276276 }
277277
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+
278303 internal func quotientAndRemainder(
279304 dividingBy other: Self
280305 ) -> (quotient: Self, remainder: Self) {
@@ -515,6 +540,13 @@ extension BinaryInteger {
515540 fileprivate var _isNegative: Bool { self < Self.zero }
516541}
517542
543+ extension FixedWidthInteger {
544+ @inline(__always)
545+ fileprivate var _twosComplement: Self {
546+ ~self &+ 1
547+ }
548+ }
549+
518550private typealias _Wide2<F: FixedWidthInteger> =
519551 (high: F, low: F.Magnitude)
520552
0 commit comments