dastal
Version:
Data Structures & Algorithms implementations
175 lines • 3.76 kB
JavaScript
;
/**
* Bit hacks for 32-bit unsigned numbers.
* @module
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.u32 = exports.reverse = exports.msps = exports.msp = exports.msb = exports.lzp = exports.lzb = exports.lsps = exports.lsp = exports.lsb = exports.isPow2 = exports.invert = exports.bitsSet = void 0;
/**
* Get the number of bits set of a 32-bit unsigned number ([source](https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel))
*
* @param a
*/
function bitsSet(a) {
a = a - ((a >>> 1) & 0x55555555);
a = (a & 0x33333333) + ((a >>> 2) & 0x33333333);
return (((a + (a >>> 4)) & 0xf0f0f0f) * 0x1010101) >>> 24;
}
exports.bitsSet = bitsSet;
/**
* Invert the bits of a 32-bit unsigned number.
*
* Example: 11 (1011) -> 4 (0100)
*
* @param a The number to invert
*
* @returns The inverted number
*/
function invert(a) {
const b = msp(a);
return u32(a ^ (b | (b - 1)));
}
exports.invert = invert;
/**
* Check whether a 32-bit unsigned number is a power of 2.
*
* Example: 8 (1000) -> true
*
* @param a The number to check
*/
function isPow2(a) {
return (a & (a - 1)) === 0;
}
exports.isPow2 = isPow2;
/**
* Get the Least Significant Bit of a 32-bit unsigned number
*
* @param a
*
* @returns The lowest bit set
*/
function lsb(a) {
return a === 0 ? -1 : 0 | Math.log2(lsp(a));
}
exports.lsb = lsb;
/**
* Get the Least Significant Power of a 32-bit unsigned number
*
* @param a
*
* @returns 2**lsb(a)
*/
function lsp(a) {
return u32(a & -a);
}
exports.lsp = lsp;
/**
* Get the Least Significant Power Set of a 32-bit unsigned number.
*
* Example: 54 (110110) -> 6 (000110)
*
* @param a
*/
function lsps(a) {
return u32(a & (lsp(a + lsp(a)) - 1));
}
exports.lsps = lsps;
/**
* Get the Least Zeroed Bit of a 32-bit unsigned number
*
* @param a
*/
function lzb(a) {
return lsb(lzp(a));
}
exports.lzb = lzb;
/**
* Get the Least Zeroed Power of a 32-bit unsigned number
*
* @param a
*
* @returns 2**lzb(a)
*/
function lzp(a) {
return u32((a + 1) & ~a);
}
exports.lzp = lzp;
/**
* Get the Most Significant Power of the Least Significant Power Set of a 32-bit unsigned number.
*
* Example: 54 (110110) -> 4 (000100)
*
* @param a
*/ /*
export function mlsp(a: number): number {
return (lsp(a + lsp(a)) >>> 1) || u32(0x80000000 & a);
}
*/
/**
* Get the Most Significant Bit of a 32-bit unsigned number
*
* @param a
*
* @returns ⌊log2(a)⌋ : the highest bit set
*/
function msb(a) {
return a === 0 ? -1 : 0 | Math.log2(u32(a));
}
exports.msb = msb;
/**
* Get the Most Significant Power of a 32-bit unsigned number
*
* @param a
*
* @returns 2**msb(a)
*/
function msp(a) {
a |= a >>> 1;
a |= a >>> 2;
a |= a >>> 4;
a |= a >>> 8;
a |= a >>> 16;
return u32((a >>> 1) + (a & 1));
}
exports.msp = msp;
/**
* Get the Most Significant Power Set of a 32-bit unsigned number.
*
* Example: 50 (110010) -> 48 (110000)
*
* @param a
*/
function msps(a) {
let b = a & -a;
while (a & (a + b)) {
a ^= b;
b = a & -a;
}
return u32(a);
}
exports.msps = msps;
/**
* Reverse a 32-bit unsigned number.
*
* Example: 50 (110010) -> 19 (010011)
*
* @param a
*/
function reverse(a) {
a = ((a & 0xaaaaaaaa) >>> 1) | ((a & 0x55555555) << 1);
a = ((a & 0xcccccccc) >>> 2) | ((a & 0x33333333) << 2);
a = ((a & 0xf0f0f0f0) >>> 4) | ((a & 0x0f0f0f0f) << 4);
a = ((a & 0xff00ff00) >>> 8) | ((a & 0x00ff00ff) << 8);
return u32((a >>> 16) | (a << 16));
}
exports.reverse = reverse;
/**
* Turn a number into an unsigned 32-bit number
*
* @param a
*/
function u32(a) {
return a >>> 0;
}
exports.u32 = u32;
//# sourceMappingURL=u32.js.map