Created
April 20, 2022 12:37
-
-
Save lancejpollard/1842289ad14508dec51f70a2d6622267 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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