Skip to content

Commit 53dba72

Browse files
committed
Use larger division steps in tobase function
1 parent 29dcc93 commit 53dba72

File tree

2 files changed

+32
-12
lines changed

2 files changed

+32
-12
lines changed

bint.lua

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ end
376376
-- @see bint.tointeger
377377
function bint.tonumber(x)
378378
if isbint(x) then
379-
if x >= BINT_MATHMININTEGER and x <= BINT_MATHMAXINTEGER then
379+
if x <= BINT_MATHMAXINTEGER and x >= BINT_MATHMININTEGER then
380380
return x:tointeger()
381381
else
382382
return tonumber(tostring(x))
@@ -431,9 +431,8 @@ function bint.tobase(x, base, unsigned)
431431
if unsigned == nil then
432432
unsigned = base ~= 10
433433
end
434-
if base == 10 or base == 16 then
435-
local inluarange = x >= BINT_MATHMININTEGER and x <= BINT_MATHMAXINTEGER
436-
if inluarange then
434+
if (base == 10 and not unsigned) or (base == 16 and unsigned) then
435+
if x <= BINT_MATHMAXINTEGER and x >= BINT_MATHMININTEGER then
437436
-- integer is small, use tostring or string.format (faster)
438437
local n = x:tointeger()
439438
if base == 10 then
@@ -448,14 +447,33 @@ function bint.tobase(x, base, unsigned)
448447
if neg then
449448
x = x:abs()
450449
end
451-
while not x:iszero() do
452-
local d
453-
x, d = xremainder(x, base)
454-
table.insert(ss, 1, BASE_LETTERS[d])
455-
end
456-
if #ss == 0 then
450+
local stop = x:iszero()
451+
if stop then
457452
return '0'
458453
end
454+
-- calculate basepow
455+
local step = 0
456+
local basepow = 1
457+
local limit = (BINT_WORDMSB - 1) // base
458+
repeat
459+
step = step + 1
460+
basepow = basepow * base
461+
until basepow >= limit
462+
-- spit out base digits
463+
while not stop do
464+
local xd
465+
x, xd = xremainder(x, basepow)
466+
stop = x:iszero()
467+
for _=1,step do
468+
local d
469+
xd, d = xd // base, xd % base
470+
if stop and xd == 0 and d == 0 then
471+
-- stop on leading zeros
472+
break
473+
end
474+
table.insert(ss, 1, BASE_LETTERS[d])
475+
end
476+
end
459477
if neg then
460478
table.insert(ss, 1, '-')
461479
end

tests.lua

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,13 +186,15 @@ local function test(bits, wordbits)
186186
assert_eq(bint.parse(1), bint(1))
187187
assert_eq(bint.parse(1.5), 1.5)
188188

189+
assert_eq(bint.tobase(math.mininteger, 10), tostring(math.mininteger))
190+
assert_eq(bint.tobase(math.maxinteger, 10), tostring(math.maxinteger))
189191
assert_eq(bint.tobase(1, 10), '1')
190192
assert_eq(bint.tobase(8, 7), '11')
191193
assert_eq(bint.tobase(1, 37), nil)
192194
assert_eq(bint.tobase(1.5, 10), nil)
193195
assert_eq(bint.tobase(0xff, 16, true), 'ff')
194196
assert_eq(bint.tobase(-0xff, 16, false), '-ff')
195-
if bits > 64 then
197+
if bits == 64 then
196198
assert_eq(bint.tobase(-1, 16, true), 'ffffffffffffffff')
197199
assert_eq(bint.tobase(-2, 16, true), 'fffffffffffffffe')
198200
end
@@ -616,7 +618,7 @@ end
616618

617619
test(64)
618620
test(64, 16)
619-
test(64, 4)
620621
test(64, 8)
622+
test(64, 4)
621623
test(128)
622624
test(256)

0 commit comments

Comments
 (0)