@@ -953,7 +953,7 @@ function bint:_add(y)
953
953
local carry = 0
954
954
for i = 1 ,BINT_SIZE do
955
955
local tmp = self [i ] + y [i ] + carry
956
- carry = tmp > BINT_WORDMAX and 1 or 0
956
+ carry = tmp >> BINT_WORDBITS
957
957
self [i ] = tmp & BINT_WORDMAX
958
958
end
959
959
return self
@@ -969,7 +969,7 @@ function bint.__add(x, y)
969
969
local carry = 0
970
970
for i = 1 ,BINT_SIZE do
971
971
local tmp = ix [i ] + iy [i ] + carry
972
- carry = tmp > BINT_WORDMAX and 1 or 0
972
+ carry = tmp >> BINT_WORDBITS
973
973
z [i ] = tmp & BINT_WORDMAX
974
974
end
975
975
return z
@@ -986,9 +986,9 @@ function bint:_sub(y)
986
986
local borrow = 0
987
987
local wordmaxp1 = BINT_WORDMAX + 1
988
988
for i = 1 ,BINT_SIZE do
989
- local res = ( self [i ] + wordmaxp1 ) - ( y [i ] + borrow )
989
+ local res = self [i ] + wordmaxp1 - y [i ] - borrow
990
990
self [i ] = res & BINT_WORDMAX
991
- borrow = res <= BINT_WORDMAX and 1 or 0
991
+ borrow = ( res >> BINT_WORDBITS ) ~ 1
992
992
end
993
993
return self
994
994
end
@@ -1003,9 +1003,9 @@ function bint.__sub(x, y)
1003
1003
local borrow = 0
1004
1004
local wordmaxp1 = BINT_WORDMAX + 1
1005
1005
for i = 1 ,BINT_SIZE do
1006
- local res = ( ix [i ] + wordmaxp1 ) - ( iy [i ] + borrow )
1006
+ local res = ix [i ] + wordmaxp1 - iy [i ] - borrow
1007
1007
z [i ] = res & BINT_WORDMAX
1008
- borrow = res <= BINT_WORDMAX and 1 or 0
1008
+ borrow = ( res >> BINT_WORDBITS ) ~ 1
1009
1009
end
1010
1010
return z
1011
1011
else
@@ -1036,7 +1036,7 @@ function bint.__mul(x, y)
1036
1036
local carry = 0
1037
1037
for k = i + j - 1 ,BINT_SIZE do
1038
1038
local tmp = z [k ] + (a & BINT_WORDMAX ) + carry
1039
- carry = tmp > BINT_WORDMAX and 1 or 0
1039
+ carry = tmp >> BINT_WORDBITS
1040
1040
z [k ] = tmp & BINT_WORDMAX
1041
1041
a = a >> BINT_WORDBITS
1042
1042
end
@@ -1138,9 +1138,9 @@ function bint.udivmod(x, y)
1138
1138
-- subtract denominator from the portion of the numerator
1139
1139
local borrow = 0
1140
1140
for i = 1 ,size do
1141
- local res = ( nume [i ] + wordmaxp1 ) - ( deno [i ] + borrow )
1141
+ local res = nume [i ] + wordmaxp1 - deno [i ] - borrow
1142
1142
nume [i ] = res & BINT_WORDMAX
1143
- borrow = res <= BINT_WORDMAX and 1 or 0
1143
+ borrow = ( res >> BINT_WORDBITS ) ~ 1
1144
1144
end
1145
1145
-- concatenate 1 to the right bit of the quotient
1146
1146
local i = (bit // BINT_WORDBITS ) + 1
@@ -1200,21 +1200,28 @@ end
1200
1200
function bint .idivmod (x , y )
1201
1201
local ix , iy = bint .tobint (x ), bint .tobint (y )
1202
1202
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
1206
1213
quot :_unm ()
1207
1214
-- round quotient towards minus infinity
1208
1215
if not rema :iszero () then
1209
1216
quot :_dec ()
1210
1217
-- adjust the remainder
1211
- if isnumneg and not isdenomneg then
1218
+ if isnumeneg and not isdenoneg then
1212
1219
rema :_unm ():_add (y )
1213
- elseif isdenomneg and not isnumneg then
1220
+ elseif isdenoneg and not isnumeneg then
1214
1221
rema :_add (y )
1215
1222
end
1216
1223
end
1217
- elseif isnumneg then
1224
+ elseif isnumeneg then
1218
1225
-- adjust the remainder
1219
1226
rema :_unm ()
1220
1227
end
@@ -1235,8 +1242,16 @@ end
1235
1242
function bint .__idiv (x , y )
1236
1243
local ix , iy = bint .tobint (x ), bint .tobint (y )
1237
1244
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
1240
1255
quot :_unm ()
1241
1256
-- round quotient towards minus infinity
1242
1257
if not rema :iszero () then
0 commit comments