@@ -3383,6 +3383,17 @@ extension FixedWidthInteger {
3383
3383
//===--- UnsignedInteger --------------------------------------------------===//
3384
3384
//===----------------------------------------------------------------------===//
3385
3385
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
+
3386
3397
/// An integer type that can represent only nonnegative values.
3387
3398
public protocol UnsignedInteger : BinaryInteger { }
3388
3399
@@ -3491,9 +3502,124 @@ extension UnsignedInteger where Self: FixedWidthInteger {
3491
3502
/// For unsigned integer types, this value is always `0`.
3492
3503
@_transparent
3493
3504
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
+ }
3494
3621
}
3495
3622
3496
-
3497
3623
//===----------------------------------------------------------------------===//
3498
3624
//===--- SignedInteger ----------------------------------------------------===//
3499
3625
//===----------------------------------------------------------------------===//
@@ -3622,6 +3748,40 @@ extension SignedInteger where Self: FixedWidthInteger {
3622
3748
// Having handled those special cases, this is safe.
3623
3749
return self % other == 0
3624
3750
}
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
+ }
3625
3785
}
3626
3786
3627
3787
/// Returns the given integer as the equivalent value in a different integer
0 commit comments