Skip to content

Commit d649b95

Browse files
committed
Micro optimizations
1 parent b6e4387 commit d649b95

File tree

2 files changed

+40
-24
lines changed

2 files changed

+40
-24
lines changed

Makefile

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
ROCKSPEC=rockspecs/bint-0.*.rockspec
2+
LUA?=lua
23

34
test:
4-
lua tests.lua
5-
lua examples/simple.lua
6-
lua examples/fibonacci.lua
7-
lua examples/factorial.lua
8-
lua examples/pi.lua
9-
lua examples/e.lua
10-
lua examples/rsa.lua
5+
$(LUA) tests.lua
6+
$(LUA) examples/simple.lua
7+
$(LUA) examples/fibonacci.lua
8+
$(LUA) examples/factorial.lua
9+
$(LUA) examples/pi.lua
10+
$(LUA) examples/e.lua
11+
$(LUA) examples/rsa.lua
1112

1213
docs:
1314
ldoc -d docs -f markdown bint.lua

bint.lua

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,7 @@ function bint:_add(y)
953953
local carry = 0
954954
for i=1,BINT_SIZE do
955955
local tmp = self[i] + y[i] + carry
956-
carry = tmp > BINT_WORDMAX and 1 or 0
956+
carry = tmp >> BINT_WORDBITS
957957
self[i] = tmp & BINT_WORDMAX
958958
end
959959
return self
@@ -969,7 +969,7 @@ function bint.__add(x, y)
969969
local carry = 0
970970
for i=1,BINT_SIZE do
971971
local tmp = ix[i] + iy[i] + carry
972-
carry = tmp > BINT_WORDMAX and 1 or 0
972+
carry = tmp >> BINT_WORDBITS
973973
z[i] = tmp & BINT_WORDMAX
974974
end
975975
return z
@@ -986,9 +986,9 @@ function bint:_sub(y)
986986
local borrow = 0
987987
local wordmaxp1 = BINT_WORDMAX + 1
988988
for i=1,BINT_SIZE do
989-
local res = (self[i] + wordmaxp1) - (y[i] + borrow)
989+
local res = self[i] + wordmaxp1 - y[i] - borrow
990990
self[i] = res & BINT_WORDMAX
991-
borrow = res <= BINT_WORDMAX and 1 or 0
991+
borrow = (res >> BINT_WORDBITS) ~ 1
992992
end
993993
return self
994994
end
@@ -1003,9 +1003,9 @@ function bint.__sub(x, y)
10031003
local borrow = 0
10041004
local wordmaxp1 = BINT_WORDMAX + 1
10051005
for i=1,BINT_SIZE do
1006-
local res = (ix[i] + wordmaxp1) - (iy[i] + borrow)
1006+
local res = ix[i] + wordmaxp1 - iy[i] - borrow
10071007
z[i] = res & BINT_WORDMAX
1008-
borrow = res <= BINT_WORDMAX and 1 or 0
1008+
borrow = (res >> BINT_WORDBITS) ~ 1
10091009
end
10101010
return z
10111011
else
@@ -1036,7 +1036,7 @@ function bint.__mul(x, y)
10361036
local carry = 0
10371037
for k=i+j-1,BINT_SIZE do
10381038
local tmp = z[k] + (a & BINT_WORDMAX) + carry
1039-
carry = tmp > BINT_WORDMAX and 1 or 0
1039+
carry = tmp >> BINT_WORDBITS
10401040
z[k] = tmp & BINT_WORDMAX
10411041
a = a >> BINT_WORDBITS
10421042
end
@@ -1138,9 +1138,9 @@ function bint.udivmod(x, y)
11381138
-- subtract denominator from the portion of the numerator
11391139
local borrow = 0
11401140
for i=1,size do
1141-
local res = (nume[i] + wordmaxp1) - (deno[i] + borrow)
1141+
local res = nume[i] + wordmaxp1 - deno[i] - borrow
11421142
nume[i] = res & BINT_WORDMAX
1143-
borrow = res <= BINT_WORDMAX and 1 or 0
1143+
borrow = (res >> BINT_WORDBITS) ~ 1
11441144
end
11451145
-- concatenate 1 to the right bit of the quotient
11461146
local i = (bit // BINT_WORDBITS) + 1
@@ -1200,21 +1200,28 @@ end
12001200
function bint.idivmod(x, y)
12011201
local ix, iy = bint.tobint(x), bint.tobint(y)
12021202
if ix and iy then
1203-
local quot, rema = bint.udivmod(ix:abs(), iy:abs())
1204-
local isnumneg, isdenomneg = ix:isneg(), iy:isneg()
1205-
if isnumneg ~= isdenomneg then
1203+
local isnumeneg = ix[BINT_SIZE] & BINT_WORDMSB ~= 0
1204+
local isdenoneg = iy[BINT_SIZE] & BINT_WORDMSB ~= 0
1205+
if isnumeneg then
1206+
ix = -ix
1207+
end
1208+
if isdenoneg then
1209+
iy = -iy
1210+
end
1211+
local quot, rema = bint.udivmod(ix, iy)
1212+
if isnumeneg ~= isdenoneg then
12061213
quot:_unm()
12071214
-- round quotient towards minus infinity
12081215
if not rema:iszero() then
12091216
quot:_dec()
12101217
-- adjust the remainder
1211-
if isnumneg and not isdenomneg then
1218+
if isnumeneg and not isdenoneg then
12121219
rema:_unm():_add(y)
1213-
elseif isdenomneg and not isnumneg then
1220+
elseif isdenoneg and not isnumeneg then
12141221
rema:_add(y)
12151222
end
12161223
end
1217-
elseif isnumneg then
1224+
elseif isnumeneg then
12181225
-- adjust the remainder
12191226
rema:_unm()
12201227
end
@@ -1235,8 +1242,16 @@ end
12351242
function bint.__idiv(x, y)
12361243
local ix, iy = bint.tobint(x), bint.tobint(y)
12371244
if ix and iy then
1238-
local quot, rema = bint.udivmod(ix:abs(), iy:abs())
1239-
if ix:isneg() ~= iy:isneg() then
1245+
local isnumeneg = ix[BINT_SIZE] & BINT_WORDMSB ~= 0
1246+
local isdenoneg = iy[BINT_SIZE] & BINT_WORDMSB ~= 0
1247+
if isnumeneg then
1248+
ix = -ix
1249+
end
1250+
if isdenoneg then
1251+
iy = -iy
1252+
end
1253+
local quot, rema = bint.udivmod(ix, iy)
1254+
if isnumeneg ~= isdenoneg then
12401255
quot:_unm()
12411256
-- round quotient towards minus infinity
12421257
if not rema:iszero() then

0 commit comments

Comments
 (0)