function randomBigInt(bits) {
const data = new BigUint64Array(Math.ceil(bits / 64))
self.crypto.getRandomValues(data)
return data.reduce((n, x, i) => n | (x << BigInt(i * 64)), 0n)
}
const n = randomBigInt(960)
const testersCoeff = []
const testersBigCoeff = []
const testers = []
let testersN = 0
const MAX = 2n ** 1023n;
const MAX2 = 2n ** 30n - 1n;
n.toString(2).length
let i = (n.toString(16).length - 1) * 4
i += 32 - Math.clz32(Number(n >> BigInt(i)))
// TODO: check nonnegative
// find upper bound
let i = 0
while (true) {
if (testersN === i) {
testersCoeff.push(32 << testersN)
testersBigCoeff.push(BigInt(testersCoeff[testersN]))
testers.push(1n << testersBigCoeff[testersN])
testersN++
}
if (n < testers[i]) break
i++
}
// determine length by bisection
i--
let r = testersCoeff[i]
let b = n >> testersBigCoeff[i]
while (i) {
i--
let a = b >> testersBigCoeff[i]
if (a)
(r += testersCoeff[i], b = a)
}
r += 32 - Math.clz32(Number(b))
// TODO: check nonnegative
// find upper bound
let i = 0
while (true) {
if (testersN === i) {
testersCoeff.push(32 << testersN)
testersBigCoeff.push(BigInt(testersCoeff[testersN]))
testers.push(1n << testersBigCoeff[testersN])
testersN++
}
if (n < testers[i]) break
i++
}
// determine length by bisection
i--
let r = testersCoeff[i]
let b = n >> testersBigCoeff[i]
while (i) {
i--
if (b < testers[i]) continue
r += testersCoeff[i]
b >>= testersBigCoeff[i]
}
r += 32 - Math.clz32(Number(b))
let v = n, len = 0;
while (v >= MAX) {
v >>= 1023n;
len += 1023;
}
len + Math.floor(Math.log2(Number(v))) + 1
let v = n, len = 0, x = 0;
while (x = v >> 1023n) {
v = x;
len += 1023;
}
len + Math.floor(Math.log2(Number(v))) + 1
// find upper bound
let k = 0
while (true) {
if (testersN === k) {
testersCoeff.push(1023 << testersN)
testersBigCoeff.push(BigInt(testersCoeff[testersN]))
testers.push(1n << testersBigCoeff[testersN])
testersN++
}
if (n < testers[k]) break
k++
}
if (!k)
return Math.floor(Math.log2(Number(n))) + 1
// determine length by bisection
k--
let i = testersCoeff[k]
let a = n >> testersBigCoeff[k]
while (k--) {
let b = a >> testersBigCoeff[k]
if (b)
(i += testersCoeff[k], a = b)
}
i + Math.floor(Math.log2(Number(a))) + 1