376376-- @see bint.tointeger
377377function 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
0 commit comments