376
376
-- @see bint.tointeger
377
377
function bint .tonumber (x )
378
378
if isbint (x ) then
379
- if x >= BINT_MATHMININTEGER and x <= BINT_MATHMAXINTEGER then
379
+ if x <= BINT_MATHMAXINTEGER and x >= BINT_MATHMININTEGER then
380
380
return x :tointeger ()
381
381
else
382
382
return tonumber (tostring (x ))
@@ -431,9 +431,8 @@ function bint.tobase(x, base, unsigned)
431
431
if unsigned == nil then
432
432
unsigned = base ~= 10
433
433
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
437
436
-- integer is small, use tostring or string.format (faster)
438
437
local n = x :tointeger ()
439
438
if base == 10 then
@@ -448,14 +447,33 @@ function bint.tobase(x, base, unsigned)
448
447
if neg then
449
448
x = x :abs ()
450
449
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
457
452
return ' 0'
458
453
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
459
477
if neg then
460
478
table.insert (ss , 1 , ' -' )
461
479
end
0 commit comments