Skip to content

Commit c7b30da

Browse files
committed
perf: fast divide shorter by longer bigint
1 parent fa7dc18 commit c7b30da

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

lib/Support/BigIntSupport.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1754,6 +1754,25 @@ static OperationStatus compute(
17541754
((quoc.digits != nullptr) != (rem.digits != nullptr)) &&
17551755
"untested -- calling with both or neither quoc and rem");
17561756

1757+
// Signal division by zero.
1758+
if (compare(rhs, 0) == 0) {
1759+
return OperationStatus::DIVISION_BY_ZERO;
1760+
}
1761+
1762+
if (lhs.numDigits < rhs.numDigits) {
1763+
// In this case, divideResultSize returns 0 and mismatches remainderResultSize
1764+
1765+
if (quoc.digits != nullptr) {
1766+
quoc.numDigits = 0;
1767+
}
1768+
1769+
if (rem.digits != nullptr) {
1770+
return initWithDigits(rem, lhs);
1771+
}
1772+
1773+
return OperationStatus::RETURNED;
1774+
}
1775+
17571776
const uint32_t resultSize = divideResultSize(lhs, rhs);
17581777
// set quoc's and rem's numDigits if their digits buffer is nullptr, which
17591778
// allows querying either for determining the result size.
@@ -1772,11 +1791,6 @@ static OperationStatus compute(
17721791
quoc.numDigits = resultSize;
17731792
rem.numDigits = resultSize;
17741793

1775-
// Signal division by zero.
1776-
if (compare(rhs, 0) == 0) {
1777-
return OperationStatus::DIVISION_BY_ZERO;
1778-
}
1779-
17801794
// tcDivide operates on unsigned number, so just like multiply, the operands
17811795
// must be negated (and the result as well, if appropriate) if they are
17821796
// negative.
@@ -1868,7 +1882,7 @@ static OperationStatus compute(
18681882
} // namespace
18691883

18701884
uint32_t divideResultSize(ImmutableBigIntRef lhs, ImmutableBigIntRef rhs) {
1871-
return div_rem::getResultSize(lhs, rhs);
1885+
return lhs.numDigits < rhs.numDigits ? 0 : div_rem::getResultSize(lhs, rhs);
18721886
}
18731887

18741888
OperationStatus
@@ -1879,7 +1893,7 @@ divide(MutableBigIntRef dst, ImmutableBigIntRef lhs, ImmutableBigIntRef rhs) {
18791893
}
18801894

18811895
uint32_t remainderResultSize(ImmutableBigIntRef lhs, ImmutableBigIntRef rhs) {
1882-
return div_rem::getResultSize(lhs, rhs);
1896+
return lhs.numDigits < rhs.numDigits ? lhs.numDigits : div_rem::getResultSize(lhs, rhs);
18831897
}
18841898

18851899
OperationStatus remainder(

0 commit comments

Comments
 (0)