@@ -3383,6 +3383,17 @@ extension FixedWidthInteger {
33833383//===--- UnsignedInteger --------------------------------------------------===//
33843384//===----------------------------------------------------------------------===//
33853385
3386+ // Implementor's note: UnsignedInteger should have required Magnitude == Self,
3387+ // because it can necessarily represent the magnitude of every value and every
3388+ // recursive generic constraint should terminate unless there is a good
3389+ // semantic reason for it not to do so.
3390+ //
3391+ // However, we cannot easily add this constraint because it changes the
3392+ // mangling of generics constrained on <T: FixedWidthInteger & UnsignedInteger>
3393+ // to be <T: FixedWidthInteger where T.Magnitude == T>. As a practical matter,
3394+ // every unsigned type will satisfy this constraint, so converting between
3395+ // Magnitude and Self in generic code is acceptable.
3396+
33863397/// An integer type that can represent only nonnegative values.
33873398public protocol UnsignedInteger : BinaryInteger { }
33883399
@@ -3491,9 +3502,124 @@ extension UnsignedInteger where Self: FixedWidthInteger {
34913502 /// For unsigned integer types, this value is always `0`.
34923503 @_transparent
34933504 public static var min : Self { return 0 }
3505+
3506+ @_alwaysEmitIntoClient
3507+ public func dividingFullWidth(
3508+ _ dividend: ( high: Self , low: Magnitude )
3509+ ) -> ( quotient: Self , remainder: Self ) {
3510+ // Validate preconditions to guarantee that the quotient is representable.
3511+ precondition ( self != . zero, " Division by zero " )
3512+ precondition ( dividend. high < self ,
3513+ " Dividend.high must be smaller than divisor " )
3514+ // UnsignedInteger should have a Magnitude = Self constraint, but does not,
3515+ // so we have to do this conversion (we can't easily add the constraint
3516+ // because it changes how generic signatures constrained to
3517+ // <FixedWidth & Unsigned> are minimized, which changes the mangling).
3518+ // In practice, "every" UnsignedInteger type will satisfy this, and if one
3519+ // somehow manages not to in a way that would break this conversion then
3520+ // a default implementation of this method never could have worked anyway.
3521+ let low = Self ( dividend. low)
3522+
3523+ // The basic algorithm is taken from Knuth (TAoCP, Vol 2, §4.3.1), using
3524+ // words that are half the size of Self (so the dividend has four words
3525+ // and the divisor has two). The fact that the denominator has exactly
3526+ // two words allows for a slight simplification vs. Knuth's Algorithm D,
3527+ // in that our computed quotient digit is always exactly right, while
3528+ // in the more general case it can be one too large, requiring a subsequent
3529+ // borrow.
3530+ //
3531+ // Knuth's algorithm (and any long division, really), requires that the
3532+ // divisor (self) be normalized (meaning that the high-order bit is set).
3533+ // We begin by counting the leading zeros so we know how many bits we
3534+ // have to shift to normalize.
3535+ let lz = leadingZeroBitCount
3536+
3537+ // If the divisor is actually a power of two, division is just a shift,
3538+ // which we can handle much more efficiently. So we do a check for that
3539+ // case and early-out if possible.
3540+ if ( self &- 1 ) & self == . zero {
3541+ let shift = Self . bitWidth - 1 - lz
3542+ let q = low &>> shift | dividend. high &<< - shift
3543+ let r = low & ( self &- 1 )
3544+ return ( q, r)
3545+ }
3546+
3547+ // Shift the divisor left by lz bits to normalize it. We shift the
3548+ // dividend left by the same amount so that we get the quotient is
3549+ // preserved (we will have to shift right to recover the remainder).
3550+ // Note that the right shift `low >> (Self.bitWidth - lz)` is
3551+ // deliberately a non-masking shift because lz might be zero.
3552+ let v = self &<< lz
3553+ let uh = dividend. high &<< lz | low >> ( Self . bitWidth - lz)
3554+ let ul = low &<< lz
3555+
3556+ // Now we have a normalized dividend (uh:ul) and divisor (v). Split
3557+ // v into half-words (vh:vl) so that we can use the "normal" division
3558+ // on Self as a word / halfword -> halfword division get one halfword
3559+ // digit of the quotient at a time.
3560+ let n_2 = Self . bitWidth/ 2
3561+ let mask = Self ( 1 ) &<< n_2 &- 1
3562+ let vh = v &>> n_2
3563+ let vl = v & mask
3564+
3565+ // For the (fairly-common) special case where vl is zero, we can simplify
3566+ // the arithmetic quite a bit:
3567+ if vl == . zero {
3568+ let qh = uh / vh
3569+ let residual = ( uh &- qh &* vh) &<< n_2 | ul &>> n_2
3570+ let ql = residual / vh
3571+
3572+ return (
3573+ // Assemble quotient from half-word digits
3574+ quotient: qh &<< n_2 | ql,
3575+ // Compute remainder (we can re-use the residual to make this simpler).
3576+ remainder: ( ( residual &- ql &* vh) &<< n_2 | ul & mask) &>> lz
3577+ )
3578+ }
3579+
3580+ // Helper function: performs a (1½ word)/word division to produce a
3581+ // half quotient word q. We'll need to use this twice to generate the
3582+ // full quotient.
3583+ //
3584+ // high is the high word of the quotient for this sub-division.
3585+ // low is the low half-word of the quotient for this sub-division (the
3586+ // high half of low must be zero).
3587+ //
3588+ // returns the quotient half-word digit. In a more general setting, this
3589+ // computed digit might be one too large, which has to be accounted for
3590+ // later on (see Knuth, Algorithm D), but when the divisor is only two
3591+ // half-words (as here), that can never happen, because we use the full
3592+ // divisor in the check for the while loop.
3593+ func generateHalfDigit( high: Self , low: Self ) -> Self {
3594+ // Get q̂ satisfying a = vh q̂ + r̂ with 0 ≤ r̂ < vh:
3595+ var ( q̂, r̂) = high. quotientAndRemainder ( dividingBy: vh)
3596+ // Knuth's "Theorem A" establishes that q̂ is an approximation to
3597+ // the quotient digit q, satisfying q ≤ q̂ ≤ q + 2. We adjust it
3598+ // downward as needed until we have the correct q.
3599+ while q̂ > mask || q̂ &* vl > ( r̂ &<< n_2 | low) {
3600+ q̂ &-= 1
3601+ r̂ &+= vh
3602+ if r̂ > mask { break }
3603+ }
3604+ return q̂
3605+ }
3606+
3607+ // Generate the first quotient digit, subtract off its product with the
3608+ // divisor to generate the residual, then compute the second quotient
3609+ // digit from that.
3610+ let qh = generateHalfDigit ( high: uh, low: ul &>> n_2)
3611+ let residual = ( uh &<< n_2 | ul &>> n_2) &- ( qh &* v)
3612+ let ql = generateHalfDigit ( high: residual, low: ul & mask)
3613+
3614+ return (
3615+ // Assemble quotient from half-word digits
3616+ quotient: qh &<< n_2 | ql,
3617+ // Compute remainder (we can re-use the residual to make this simpler).
3618+ remainder: ( ( residual &<< n_2 | ul & mask) &- ( ql &* v) ) &>> lz
3619+ )
3620+ }
34943621}
34953622
3496-
34973623//===----------------------------------------------------------------------===//
34983624//===--- SignedInteger ----------------------------------------------------===//
34993625//===----------------------------------------------------------------------===//
@@ -3622,6 +3748,40 @@ extension SignedInteger where Self: FixedWidthInteger {
36223748 // Having handled those special cases, this is safe.
36233749 return self % other == 0
36243750 }
3751+
3752+ @_alwaysEmitIntoClient
3753+ public func dividingFullWidth(
3754+ _ dividend: ( high: Self , low: Magnitude )
3755+ ) -> ( quotient: Self , remainder: Self ) {
3756+ // Get magnitude of dividend:
3757+ var magnitudeHigh = Magnitude ( truncatingIfNeeded: dividend. high)
3758+ var magnitudeLow = dividend. low
3759+ if dividend. high < . zero {
3760+ let carry : Bool
3761+ ( magnitudeLow, carry) = ( ~ magnitudeLow) . addingReportingOverflow ( 1 )
3762+ magnitudeHigh = ~ magnitudeHigh &+ ( carry ? 1 : 0 )
3763+ }
3764+ // Do division on magnitudes (using unsigned implementation):
3765+ let ( unsignedQuotient, unsignedRemainder) = magnitude. dividingFullWidth (
3766+ ( high: magnitudeHigh, low: magnitudeLow)
3767+ )
3768+ // Fixup sign: quotient is negative if dividend and divisor disagree.
3769+ // We will also trap here if the quotient does not fit in Self.
3770+ let quotient : Self
3771+ if self ^ dividend. high < . zero {
3772+ // It is possible that the quotient is representable but its magnitude
3773+ // is not representable as Self (if quotient is Self.min), so we have
3774+ // to handle that case carefully here.
3775+ precondition ( unsignedQuotient <= Self . min. magnitude,
3776+ " Quotient is not representable. " )
3777+ quotient = Self ( truncatingIfNeeded: 0 &- unsignedQuotient)
3778+ } else {
3779+ quotient = Self ( unsignedQuotient)
3780+ }
3781+ var remainder = Self ( unsignedRemainder)
3782+ if dividend. high < . zero { remainder = 0 &- remainder }
3783+ return ( quotient, remainder)
3784+ }
36253785}
36263786
36273787/// Returns the given integer as the equivalent value in a different integer
0 commit comments