Skip to content

Commit 01ab72c

Browse files
committed
Optimization in udivmod to do less iterations
1 parent 6db920b commit 01ab72c

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

bint.lua

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,19 +1065,23 @@ function bint.udivmod(x, y)
10651065
local divisor = bint_assert_convert(y)
10661066
local quot = bint.zero()
10671067
assert(not divisor:iszero(), 'attempt to divide by zero')
1068-
if dividend:ult(divisor) then
1068+
if divisor:isone() then
1069+
return dividend, bint.zero()
1070+
elseif dividend:ult(divisor) then
10691071
return quot, dividend
10701072
end
10711073
-- align leftmost digits in dividend and divisor
10721074
local divisorlbit = findleftbit(divisor)
1073-
local divdendlbit, size = findleftbit(dividend)
1075+
local divdendlbit, divdendsize = findleftbit(dividend)
10741076
local bit = divdendlbit - divisorlbit
10751077
divisor = divisor << bit
10761078
local wordmaxp1 = BINT_WORDMAX + 1
10771079
local wordbitsm1 = BINT_WORDBITS - 1
1080+
local divisorsize = divdendsize
10781081
while bit >= 0 do
10791082
-- compute divisor <= dividend
10801083
local le = true
1084+
local size = math.max(divdendsize, divisorsize)
10811085
for i=size,1,-1 do
10821086
local a, b = divisor[i], dividend[i]
10831087
if a ~= b then
@@ -1099,10 +1103,20 @@ function bint.udivmod(x, y)
10991103
quot[i] = quot[i] | (1 << (bit % BINT_WORDBITS))
11001104
end
11011105
-- shift right the divisor in one bit
1102-
for i=1,size-1 do
1106+
for i=1,divisorsize-1 do
11031107
divisor[i] = ((divisor[i] >> 1) | (divisor[i+1] << wordbitsm1)) & BINT_WORDMAX
11041108
end
1105-
divisor[size] = divisor[size] >> 1
1109+
local lastdivisorword = divisor[divisorsize] >> 1
1110+
divisor[divisorsize] = lastdivisorword
1111+
-- recalculate divisor size (optimization)
1112+
if lastdivisorword == 0 then
1113+
while divisor[divisorsize] == 0 do
1114+
divisorsize = divisorsize - 1
1115+
end
1116+
if divisorsize == 0 then
1117+
break
1118+
end
1119+
end
11061120
-- decrement current set bit for the quotient
11071121
bit = bit - 1
11081122
end

0 commit comments

Comments
 (0)