@@ -34,7 +34,6 @@ using strings or large tables, so regarding that aspect this library should be m
3434
3535The main design goal of this library is to be small, correct, self contained and use few
3636resources while retaining acceptable performance and feature completeness.
37- Clarity of the code is also highly valued.
3837
3938The library is designed to follow recent Lua integer semantics, this means that
4039integer 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
865864end
@@ -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
904924end
905925
0 commit comments