This is the naive algorithm that calculates integer log2(n),
function ilog2(n) { // n is a positive non-zero BigInt
const C1 = BigInt(1)
const C2 = BigInt(2)
for(var count=0; n>C1; count++) n = n/C2
return count
} // example ilog2(16n)==4
I am testing optimizations (see example below) but they are not "for log2", as commented here.
There are something better using WebAssembly?
PS: if it is not possible a generic solution, to solve my problem I can use functions like ilog2_64bits(n)
, with WebAssembly truncating or ignoring some bits of input BigInt.
non-WebAssembly
Example of not so optimized in pure Javascript (ideal is WebAssembly!)... Trying adaptation of integerLogarithm() of BigInteger.js:
function ilog2_pe(value, base=2n) {
// example: ilog2_pe(255n) returns { p: 128n, e: 7n }
if (base <= value) {
let i = ilog2_pe(value, base**2n);
let t = i.p*base
return (t <= value)
? { p: t, e: i.e*2n + 1n }
: { p: i.p, e: i.e*2n }
}
return { p: 1n, e: 0n };
}
function ilog2_str(n) { // 2*faster!
return n.toString(2).length - 1
}
PS: it is running in modern browsers and last versions of NodeJS.
About performance... ilog2_pe(x64bits)
is 4 times faster tham the naive ilog2()
, ilog2_pe(x1024bits)
is ~9 times faster... Was expected... But:
Any non-WebAssembly solution has so ugly performance, even for 512, 1024, 2048 bits... counting string digits with ilog_str()
is 2 times faster!
For less tham 64 bits is 3 or more times faster.