             let r = uh - q * vn1 // Remainder, less than vn1
             let p = q * vn0
             // q is often already correct, but sometimes the approximation overshoots by at most 2.
-            // The code that follows checks for this while being careful not to need double-digit operations.
+            // The code that follows checks for this while being careful to only perform single-digit operations.
             if q.high == 0 && p <= (r << halfShift) | ul { return q }
             if (r + vn1).high != 0 { return q - 1 }
-            if (q - 1).high == 0 && (p - vn0) <= ((r + vn1) << halfShift) | ul { return q - 1 }
-            assert((r + 2 * vn1).high != 0 || p - 2 * vn0 <= (r + 2 * vn1) << halfShift | ul)
+            if (q - 1).high == 0 && (p - vn0) <= Digit(high: r + vn1, low: ul) { return q - 1 }
+            assert((r + 2 * vn1).high != 0 || p - 2 * vn0 <= Digit(high: r + 2 * vn1, low: ul))
             return q - 2
         }
         /// Divide 3 half-digits by 2 half-digits to get a half-digit quotient and a full-digit remainder.
         /// - Requires: uh < vn && ul.high == 0 && vn.rank = width(Digit)
         func divmod(uh: Digit, _ ul: Digit, _ v: Digit) -> (div: Digit, mod: Digit) {
             let q = quotient(uh, ul, v)
-            // Note that `uh << halfShift` will shift off a couple of bits, and `q * v` and the
+            // Note that `uh.low` masks off a couple of bits, and `q * v` and the
             // subtraction are likely to overflow. Despite this, the end result (remainder) will
             // still be correct and it will fit inside a single (full) Digit.
-            let r = ((uh << halfShift) | ul) &- q &* v
+            let r = Digit(high: uh.low, low: ul) &- q &* v
             assert(r < v)
             return (q, r)
         }

        let (q1, un21) = divmod(un32, un1, vn)
        let (q0, rn) = divmod(un21, un0, vn)

        // Undo normalization of remainder and combine the two halves of the quotient.
        let mod = rn >> z
        let div = Digit(high: q1, low: q0)
        return (div, mod)

        self = (high << Digit.halfShift) | low
    }

    /// Divide the two-digit number `(u1, u0)` by a single digit `v` and return the quotient and remainder.
    /// - Requires: `u1 < v`, so that the result will fit in a single digit.
    /// - Complexity: O(1) with 2 divisions, 6 multiplications and ~12 or so additions/subtractions.
    @warn_unused_result
    public static func fullDivide(u1: Digit, _ u0: Digit, _ v: Digit) -> (div: Digit, mod: Digit) {
        // Division is complicated; doing it with single-digit operations is maddeningly complicated.
        // This is a Swift adaptation for "divlu2" in Hacker's Delight,
        // which is in turn a C adaptation of Knuth's Algorithm D (TAOCP vol 2, 4.3.1).
        precondition(u1 < v)

        /// Find the half-digit quotient in `(uh, ul) / vn`, which must be normalized.
