Skip to content

Commit c9f932d

Browse files
committed
Optimize even more udivmod
1 parent 52c4eac commit c9f932d

File tree

3 files changed

+31
-13
lines changed

3 files changed

+31
-13
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ Bint stands for Big Integer.
1616

1717
The main design goal of this library is to be small, correct, self contained and use few
1818
resources while retaining acceptable performance and feature completeness.
19-
Clarity of the code is also highly valued.
2019

2120
The library is designed to follow recent Lua integer semantics, this means that
2221
integer overflow warps around,

bint.lua

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ using strings or large tables, so regarding that aspect this library should be m
3434
3535
The main design goal of this library is to be small, correct, self contained and use few
3636
resources while retaining acceptable performance and feature completeness.
37-
Clarity of the code is also highly valued.
3837
3938
The library is designed to follow recent Lua integer semantics, this means that
4039
integer overflow warps around,
@@ -859,7 +858,7 @@ local function findleftbit(x)
859858
v = v >> 1
860859
j = j + 1
861860
until v == 0
862-
return (i-1)*BIGINT_WORDBITS + j - 1
861+
return (i-1)*BIGINT_WORDBITS + j - 1, i
863862
end
864863
end
865864
end
@@ -881,25 +880,46 @@ function bint.udivmod(x, y)
881880
return bint.zero(), dividend
882881
end
883882
-- align leftmost digits in dividend and divisor
884-
local bit = findleftbit(dividend) - findleftbit(divisor)
883+
local divisorlbit = findleftbit(divisor)
884+
local divdendlbit, size = findleftbit(dividend)
885+
local bit = divdendlbit - divisorlbit
885886
divisor = divisor << bit
886887
-- set quotient to 0
887888
local quot = bint.zero()
889+
local wordmaxp1 = BIGINT_WORDMAX + 1
890+
local wordbitsm1 = BIGINT_WORDBITS - 1
888891
while bit >= 0 do
892+
-- compute divisor <= dividend
893+
local le = true
894+
for i=size,1,-1 do
895+
local a, b = divisor[i], dividend[i]
896+
if a ~= b then
897+
le = a < b
898+
break
899+
end
900+
end
889901
-- if the portion of the dividend above the divisor is greater or equal than to the divisor
890-
if divisor:ule(dividend) then
902+
if le then
891903
-- subtract divisor from the portion of the dividend
892-
dividend:_sub(divisor)
904+
local borrow = 0
905+
for i=1,size do
906+
local res = (dividend[i] + wordmaxp1) - (divisor[i] + borrow)
907+
dividend[i] = res & BIGINT_WORDMAX
908+
borrow = res <= BIGINT_WORDMAX and 1 or 0
909+
end
893910
-- concatenate 1 to the right bit of the quotient
894911
local i = (bit // BIGINT_WORDBITS) + 1
895912
quot[i] = quot[i] | (1 << (bit % BIGINT_WORDBITS))
896913
end
897-
-- shift current set bit for the quotient
898-
bit = bit - 1
899914
-- shift right the divisor in one bit
900-
divisor:_shrone()
915+
for i=1,size-1 do
916+
divisor[i] = ((divisor[i] >> 1) | (divisor[i+1] << wordbitsm1)) & BIGINT_WORDMAX
917+
end
918+
divisor[size] = divisor[size] >> 1
919+
-- decrement current set bit for the quotient
920+
bit = bit - 1
901921
end
902-
-- the left dividend is the remainder
922+
-- the remaining dividend is the remainder
903923
return quot, dividend
904924
end
905925

docs/index.html

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,7 @@ <h1>Module <code>bint</code></h1>
5555
<h2>Design goals</h2>
5656

5757
<p>The main design goal of this library is to be small, correct, self contained and use few
58-
resources while retaining acceptable performance and feature completeness.
59-
Clarity of the code is also highly valued.</p>
58+
resources while retaining acceptable performance and feature completeness.</p>
6059

6160
<p>The library is designed to follow recent Lua integer semantics, this means that
6261
integer overflow warps around,
@@ -2038,7 +2037,7 @@ <h3>See also:</h3>
20382037
</div> <!-- id="main" -->
20392038
<div id="about">
20402039
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
2041-
<i style="float:right;">Last updated 2020-07-07 16:24:29 </i>
2040+
<i style="float:right;">Last updated 2020-07-07 23:25:14 </i>
20422041
</div> <!-- id="about" -->
20432042
</div> <!-- id="container" -->
20442043
</body>

0 commit comments

Comments
 (0)