Skip to content

Instantly share code, notes, and snippets.

@lancejpollard
Created April 20, 2022 12:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lancejpollard/1842289ad14508dec51f70a2d6622267 to your computer and use it in GitHub Desktop.
Save lancejpollard/1842289ad14508dec51f70a2d6622267 to your computer and use it in GitHub Desktop.
const BINARY_LEADING_ZERO_TABLE = makeLeadingZeroTable()
const BINARY_TRAILING_ZERO_CONSTANT = 0x077cb531
const BINARY_TRAILING_ZERO_TABLE = makeDeBruijnTrailingZeroTable(5, BINARY_TRAILING_ZERO_CONSTANT)
function countTrailingZeroes32(n) {
return BINARY_TRAILING_ZERO_TABLE[((n & -n) * BINARY_TRAILING_ZERO_CONSTANT) >>> 27];
}
function countTrailingZeroes16(n) {
return countTrailingZeroes32(n)
}
function countTrailingZeroes8(n) {
return countTrailingZeroes32(n)
}
function countTrailingOnes32(x) {
return countTrailingZeroes32(~x >>> 0)
}
function countTrailingOnes16(x) {
return countTrailingZeroes32(~x >>> 0)
}
function countTrailingOnes8(x) {
return countTrailingZeroes32(~x >>> 0)
}
function countLeadingZeroes32(n)
{
let accum = BINARY_LEADING_ZERO_TABLE[n >>> 24];
if (accum === 8) {
accum += BINARY_LEADING_ZERO_TABLE[(n >>> 16)]
}
if (accum === 16) {
accum += BINARY_LEADING_ZERO_TABLE[(n >>> 8)]
}
if (accum === 24) {
accum += BINARY_LEADING_ZERO_TABLE[ n ]
}
return accum;
}
function countLeadingZeroes16(n)
{
let accum = BINARY_LEADING_ZERO_TABLE[n >>> 8]
if (accum === 8) {
accum += BINARY_LEADING_ZERO_TABLE[n]
}
return accum;
}
function countLeadingZeroes8(n)
{
return BINARY_LEADING_ZERO_TABLE[n]
}
function countLeadingOnes32(n) {
return countLeadingZeroes32(~n >>> 0 & 0xffffffff)
}
function countLeadingOnes16(n) {
return countLeadingZeroes16(~n >>> 0 & 0xffff)
}
function countLeadingOnes8(n) {
return countLeadingZeroes8(~n >>> 0 & 0xff)
}
function makeLeadingZeroTable() {
let i = 0
const table = new Uint8Array(256).fill(0)
while (i < 256) {
let count = 8
let index = i
while (index > 0) {
index = (index / 2) | 0
count--
}
table[i] = count
i++
}
return table
}
function makeDeBruijnTrailingZeroTable(exponent, deBruijnConstant) {
const n = 2 ** exponent
const table = new Array(n)
for(let i = 0; i < n; ++i) {
table[(deBruijnConstant << i) >>> (n - exponent)] = i;
}
return table;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment