Skip to content

Commit 090a047

Browse files
authored
[test/Prototypes] Fix DoubleWidth think-os (#70289)
1 parent 703a471 commit 090a047

File tree

1 file changed

+28
-9
lines changed

1 file changed

+28
-9
lines changed

test/Prototypes/DoubleWidth.swift.gyb

+28-9
Original file line numberDiff line numberDiff line change
@@ -393,8 +393,10 @@ extension DoubleWidth : FixedWidthInteger {
393393

394394
let low =
395395
DoubleWidth<Low>(mid1.partial, a.partial)
396+
let (sum_, overflow_) =
397+
mid1.carry.addingReportingOverflow(mid2.partial)
396398
let high =
397-
DoubleWidth(High(mid2.carry + d.carry), mid1.carry + mid2.partial)
399+
DoubleWidth(High(mid2.carry + d.carry + (overflow_ ? 1 : 0)), sum_)
398400

399401
if isNegative {
400402
let (lowComplement, overflow) = (~low).addingReportingOverflow(1)
@@ -595,10 +597,14 @@ extension DoubleWidth : UnsignedInteger where Base : UnsignedInteger {
595597
) -> (quotient: Low, remainder: Magnitude) {
596598
// The following invariants are guaranteed to hold by dividingFullWidth or
597599
// quotientAndRemainder before this method is invoked:
598-
assert(lhs.high != (0 as Low))
599600
assert(rhs.leadingZeroBitCount == 0)
600601
assert(Magnitude(lhs.high, lhs.mid) < rhs)
601602

603+
guard lhs.high != (0 as Low) else {
604+
let lhs_ = Magnitude(lhs.mid, lhs.low)
605+
return lhs_ < rhs ? (0, lhs_) : (1, lhs_ &- rhs)
606+
}
607+
602608
// Estimate the quotient.
603609
var quotient = lhs.high == rhs.high
604610
? Low.max
@@ -699,12 +705,13 @@ extension DoubleWidth : UnsignedInteger where Base : UnsignedInteger {
699705

700706
// Left shift both rhs and lhs, then divide and right shift the remainder.
701707
let shift = rhs.leadingZeroBitCount
708+
// Note the use of `>>` instead of `&>>` below,
709+
// as `high` should be zero if `shift` is zero.
702710
let high = (lhs >> (Magnitude.bitWidth &- shift)).low
703711
let rhs = rhs &<< shift
704712
let lhs = lhs &<< shift
705-
let (quotient, remainder) = high == (0 as Low)
706-
? (1, lhs &- rhs)
707-
: Magnitude._divide((high, lhs.high, lhs.low), by: rhs)
713+
let (quotient, remainder) =
714+
Magnitude._divide((high, lhs.high, lhs.low), by: rhs)
708715
return (Magnitude(0, quotient), remainder &>> shift)
709716
}
710717
}
@@ -813,15 +820,27 @@ dwTests.test("Arithmetic/unsigned") {
813820
expectEqual(lhs % rhs, 4096)
814821
}
815822
do {
816-
let lhs = DoubleWidth<UInt64>((high: 0xa0c7d7165cf01386, low: 0xbf3f66a93056143f))
817-
let rhs = DoubleWidth<UInt64>((high: 0x9ac3a19b1e7d6b83, low: 0x513929792d588736))
823+
let lhs = UInt128((high: 0xa0c7d7165cf01386, low: 0xbf3f66a93056143f))
824+
let rhs = UInt128((high: 0x9ac3a19b1e7d6b83, low: 0x513929792d588736))
818825
expectEqual(String(lhs % rhs), "7997221894243298914179865336050715913")
819826
}
820827
do {
821-
let lhs = DoubleWidth<UInt64>((high: 0xea8a9116b7af33b7, low: 0x3d9d6779ddd22ca3))
822-
let rhs = DoubleWidth<UInt64>((high: 0xc3673efc7f1f37cc, low: 0x312f661057d0ba94))
828+
let lhs = UInt128((high: 0xea8a9116b7af33b7, low: 0x3d9d6779ddd22ca3))
829+
let rhs = UInt128((high: 0xc3673efc7f1f37cc, low: 0x312f661057d0ba94))
823830
expectEqual(String(lhs % rhs), "52023287460685389410162512181093036559")
824831
}
832+
do {
833+
let lhs = UInt256("2369676578372158364766242369061213561181961479062237766620")!
834+
let rhs = UInt256("102797312405202436815976773795958969482")!
835+
expectEqual(String(lhs / rhs), "23051931251193218442")
836+
}
837+
do {
838+
let lhs = UInt256("96467201117289166187766181030232879447148862859323917044548749804018359008044")!
839+
let rhs = UInt256("4646260627574879223760172113656436161581617773435991717024")!
840+
expectEqual(String(lhs / rhs), "20762331011904583253")
841+
}
842+
843+
expectTrue((0xff01 as DoubleWidth<UInt8>).multipliedFullWidth(by: 0x101) == (high: 256, low: 1))
825844
}
826845

827846
dwTests.test("Arithmetic/signed") {

0 commit comments

Comments
 (0)