UNPKG

extra-bit

Version:

The [bit] is a basic unit of information in information theory, computing.<br>

233 lines • 14.6 kB
// METHODS // ======= // Get integer with 1s of specified width in bits. function ones(w) { return (1 << w) - 1; } /** * Get bits at specified index. * @param x an int32 * @param i bit index * @param w bit width [1] */ export function get(x, i, w = 1) { return x >>> i & ones(w); } /** * Get bits as per mask. * @param x an int32 * @param m bit mask */ export function getAs(x, m) { return x & m; } /** * Set bits at specified index. * @param x an int32 * @param i bit index * @param v bit value [1] * @param w bit width [1] */ export function set(x, i, v = 1, w = 1) { return x & ~(ones(w) << i) | v << i; } /** * Set bits as per mask. * @param x an int32 * @param m bit mask * @param f bit value [1] */ export function setAs(x, m, f = 1) { return x & ~m | -f & m; } /** * Toggle bits at specified index. * @param x an int32 * @param i bit index * @param w bit width [1] */ export function toggle(x, i, w = 1) { return x ^ ones(w) << i; } /** * Toggle bits as per mask. * @param x an int32 * @param m bit mask */ export function toggleAs(x, m) { return x ^ m; } /** * Swap bit sequences at specified indices. * @param x an int32 * @param i first bit index * @param j second bit index * @param w bit width [1] */ export function swap(x, i, j, w = 1) { const t = (x >>> i ^ x >>> j) & ones(w); return x ^ (t << i | t << j); } const MOD37_POS32 = [ 32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, 20, 8, 19, 18 ]; /** * Find index of first set bit from LSB. * @param x an int32 */ export function scan(x) { return MOD37_POS32[(-x & x) % 37]; } const DEBRUIJN_POS32 = [ 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 ]; /** * Find index of first set bit from MSB. * @param x an int32 */ export function scanReverse(x) { x |= x >>> 1; x |= x >>> 2; x |= x >>> 4; x |= x >>> 8; x |= x >>> 16; return DEBRUIJN_POS32[x * 0x07C4ACDD >>> 27]; } /** * Count bits set. * @param x an int32 */ export function count(x) { x = x - (x >>> 1 & 0x55555555); x = (x & 0x33333333) + (x >>> 2 & 0x33333333); return (x + (x >>> 4) & 0x0F0F0F0F) * 0x01010101 >>> 24; } // Calculate 1-bit parity. function parity1(x) { x ^= x >>> 16; x ^= x >>> 8; x ^= x >>> 4; x &= 0xF; return 0x6996 >>> x & 1; } /** * Calculate n-bit parity. * @param x an int32 * @param n number of bits [1] */ export function parity(x, n = 1) { if (n === 1) return parity1(x); const m = (1 << n) - 1; let a = 0 | 0; while(x){ a ^= x & m; x >>>= n; } return a; } /** * Rotate bits by a certain amount. * @param x an int32 * @param n rotate amount (+ve: left, -ve: right) */ export function rotate(x, n = 0) { return n < 0 ? x << 32 + n | x >>> -n : x << n | x >> 32 - n; } /** * Reverse all bits. * @param x an int32 */ export function reverse(x) { x = x >>> 1 & 0x55555555 | (x & 0x55555555) << 1; x = x >>> 2 & 0x33333333 | (x & 0x33333333) << 2; x = x >>> 4 & 0x0F0F0F0F | (x & 0x0F0F0F0F) << 4; x = x >>> 8 & 0x00FF00FF | (x & 0x00FF00FF) << 8; return x >>> 16 | x << 16; } /** * Merge bits as per mask. * @param x first int32 * @param y second int32 * @param m bit mask (0 ⇒ from x) */ export function merge(x, y, m) { return x ^ (x ^ y) & m; } /** * Interleave bits of two int16s. * @param x first int16 * @param y second int16 * @returns int32 */ export function interleave(x, y) { x = (x | x << 8) & 0x00FF00FF; x = (x | x << 4) & 0x0F0F0F0F; x = (x | x << 2) & 0x33333333; x = (x | x << 1) & 0x55555555; y = (y | y << 8) & 0x00FF00FF; y = (y | y << 4) & 0x0F0F0F0F; y = (y | y << 2) & 0x33333333; y = (y | y << 1) & 0x55555555; return y | x << 1; } /** * Sign extend variable bit-width integer. * @param x variable bit-width integer * @param w bit width (32) */ export function signExtend(x, w = 32) { w = 32 - w; return x << w >> w; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9leHRyYS1iaXQvZXh0cmEtYml0L2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIE1FVEhPRFNcbi8vID09PT09PT1cblxuLy8gR2V0IGludGVnZXIgd2l0aCAxcyBvZiBzcGVjaWZpZWQgd2lkdGggaW4gYml0cy5cbmZ1bmN0aW9uIG9uZXModzogbnVtYmVyKSB7XG4gIHJldHVybiAoMTw8dykgLSAxO1xufVxuXG5cbi8qKlxuICogR2V0IGJpdHMgYXQgc3BlY2lmaWVkIGluZGV4LlxuICogQHBhcmFtIHggYW4gaW50MzJcbiAqIEBwYXJhbSBpIGJpdCBpbmRleFxuICogQHBhcmFtIHcgYml0IHdpZHRoIFsxXVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0KHg6IG51bWJlciwgaTogbnVtYmVyLCB3OiBudW1iZXI9MSk6IG51bWJlciB7XG4gIHJldHVybiAoeD4+PmkpICYgb25lcyh3KTtcbn1cblxuXG4vKipcbiAqIEdldCBiaXRzIGFzIHBlciBtYXNrLlxuICogQHBhcmFtIHggYW4gaW50MzJcbiAqIEBwYXJhbSBtIGJpdCBtYXNrXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRBcyh4OiBudW1iZXIsIG06IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiB4ICYgbTtcbn1cblxuXG4vKipcbiAqIFNldCBiaXRzIGF0IHNwZWNpZmllZCBpbmRleC5cbiAqIEBwYXJhbSB4IGFuIGludDMyXG4gKiBAcGFyYW0gaSBiaXQgaW5kZXhcbiAqIEBwYXJhbSB2IGJpdCB2YWx1ZSBbMV1cbiAqIEBwYXJhbSB3IGJpdCB3aWR0aCBbMV1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldCh4OiBudW1iZXIsIGk6IG51bWJlciwgdjogbnVtYmVyPTEsIHc6IG51bWJlcj0xKTogbnVtYmVyIHtcbiAgcmV0dXJuICh4ICYgfihvbmVzKHcpPDxpKSkgfCAodjw8aSk7XG59XG5cblxuLyoqXG4gKiBTZXQgYml0cyBhcyBwZXIgbWFzay5cbiAqIEBwYXJhbSB4IGFuIGludDMyXG4gKiBAcGFyYW0gbSBiaXQgbWFza1xuICogQHBhcmFtIGYgYml0IHZhbHVlIFsxXVxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0QXMoeDogbnVtYmVyLCBtOiBudW1iZXIsIGY6IG51bWJlcj0xKTogbnVtYmVyIHtcbiAgcmV0dXJuICh4ICYgfm0pIHwgKC1mICYgbSk7XG59XG5cblxuLyoqXG4gKiBUb2dnbGUgYml0cyBhdCBzcGVjaWZpZWQgaW5kZXguXG4gKiBAcGFyYW0geCBhbiBpbnQzMlxuICogQHBhcmFtIGkgYml0IGluZGV4XG4gKiBAcGFyYW0gdyBiaXQgd2lkdGggWzFdXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b2dnbGUoeDogbnVtYmVyLCBpOiBudW1iZXIsIHc6IG51bWJlcj0xKTogbnVtYmVyIHtcbiAgcmV0dXJuIHggXiAob25lcyh3KTw8aSk7XG59XG5cblxuLyoqXG4gKiBUb2dnbGUgYml0cyBhcyBwZXIgbWFzay5cbiAqIEBwYXJhbSB4IGFuIGludDMyXG4gKiBAcGFyYW0gbSBiaXQgbWFza1xuICovXG5leHBvcnQgZnVuY3Rpb24gdG9nZ2xlQXMoeDogbnVtYmVyLCBtOiBudW1iZXIpOiBudW1iZXIge1xuICByZXR1cm4geCBeIG07XG59XG5cblxuLyoqXG4gKiBTd2FwIGJpdCBzZXF1ZW5jZXMgYXQgc3BlY2lmaWVkIGluZGljZXMuXG4gKiBAcGFyYW0geCBhbiBpbnQzMlxuICogQHBhcmFtIGkgZmlyc3QgYml0IGluZGV4XG4gKiBAcGFyYW0gaiBzZWNvbmQgYml0IGluZGV4XG4gKiBAcGFyYW0gdyBiaXQgd2lkdGggWzFdXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzd2FwKHg6IG51bWJlciwgaTogbnVtYmVyLCBqOiBudW1iZXIsIHc6IG51bWJlcj0xKTogbnVtYmVyIHtcbiAgY29uc3QgdCA9ICgoeD4+PmkpXih4Pj4+aikpICYgb25lcyh3KTtcbiAgcmV0dXJuIHggXiAoKHQ8PGkpfCh0PDxqKSk7XG59XG5cblxuY29uc3QgTU9EMzdfUE9TMzI6IG51bWJlcltdID0gW1xuICAzMiwgMCwgMSwgMjYsIDIsIDIzLCAyNywgMCwgMywgMTYsIDI0LCAzMCwgMjgsIDExLCAwLCAxMywgNCwgNywgMTcsIDAsXG4gIDI1LCAyMiwgMzEsIDE1LCAyOSwgMTAsIDEyLCA2LCAwLCAyMSwgMTQsIDksIDUsIDIwLCA4LCAxOSwgMThcbl07XG5cblxuLyoqXG4gKiBGaW5kIGluZGV4IG9mIGZpcnN0IHNldCBiaXQgZnJvbSBMU0IuXG4gKiBAcGFyYW0geCBhbiBpbnQzMlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2Nhbih4OiBudW1iZXIpOiBudW1iZXIge1xuICByZXR1cm4gTU9EMzdfUE9TMzJbKC14ICYgeCkgJSAzN107XG59XG5cblxuY29uc3QgREVCUlVJSk5fUE9TMzI6IG51bWJlcltdID0gW1xuICAwLCAgOSwgIDEsIDEwLCAxMywgMjEsICAyLCAyOSwgMTEsIDE0LCAxNiwgMTgsIDIyLCAyNSwgIDMsIDMwLFxuICA4LCAxMiwgMjAsIDI4LCAxNSwgMTcsIDI0LCAgNywgMTksIDI3LCAyMywgIDYsIDI2LCAgNSwgIDQsIDMxXG5dO1xuXG5cbi8qKlxuICogRmluZCBpbmRleCBvZiBmaXJzdCBzZXQgYml0IGZyb20gTVNCLlxuICogQHBhcmFtIHggYW4gaW50MzJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNjYW5SZXZlcnNlKHg6IG51bWJlcik6IG51bWJlciB7XG4gIHggfD0geD4+PjE7XG4gIHggfD0geD4+PjI7XG4gIHggfD0geD4+PjQ7XG4gIHggfD0geD4+Pjg7XG4gIHggfD0geD4+PjE2O1xuICByZXR1cm4gREVCUlVJSk5fUE9TMzJbKHgqMHgwN0M0QUNERCk+Pj4yN107XG59XG5cblxuLyoqXG4gKiBDb3VudCBiaXRzIHNldC5cbiAqIEBwYXJhbSB4IGFuIGludDMyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb3VudCh4OiBudW1iZXIpOiBudW1iZXIge1xuICB4ID0geCAtICgoeD4+PjEpICYgMHg1NTU1NTU1NSk7XG4gIHggPSAoeCAmIDB4MzMzMzMzMzMpICsgKCh4Pj4+MikgJiAweDMzMzMzMzMzKTtcbiAgcmV0dXJuICgoeCArICh4Pj4+NCkgJiAweDBGMEYwRjBGKSAqIDB4MDEwMTAxMDEpPj4+MjQ7XG59XG5cblxuLy8gQ2FsY3VsYXRlIDEtYml0IHBhcml0eS5cbmZ1bmN0aW9uIHBhcml0eTEoeDogbnVtYmVyKTogbnVtYmVyIHtcbiAgeCBePSB4Pj4+MTY7XG4gIHggXj0geD4+Pjg7XG4gIHggXj0geD4+PjQ7XG4gIHggJj0gMHhGO1xuICByZXR1cm4gKDB4Njk5Nj4+PngpICYgMTtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgbi1iaXQgcGFyaXR5LlxuICogQHBhcmFtIHggYW4gaW50MzJcbiAqIEBwYXJhbSBuIG51bWJlciBvZiBiaXRzIFsxXVxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyaXR5KHg6IG51bWJlciwgbjogbnVtYmVyPTEpOiBudW1iZXIge1xuICBpZiAobj09PTEpIHJldHVybiBwYXJpdHkxKHgpO1xuICBjb25zdCBtID0gKDE8PG4pLTE7IGxldCBhID0gMHwwO1xuICB3aGlsZSAoeCkge1xuICAgIGEgXj0geCZtO1xuICAgIHggPj4+PSBuO1xuICB9XG4gIHJldHVybiBhO1xufVxuXG5cbi8qKlxuICogUm90YXRlIGJpdHMgYnkgYSBjZXJ0YWluIGFtb3VudC5cbiAqIEBwYXJhbSB4IGFuIGludDMyXG4gKiBAcGFyYW0gbiByb3RhdGUgYW1vdW50ICgrdmU6IGxlZnQsIC12ZTogcmlnaHQpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByb3RhdGUoeDogbnVtYmVyLCBuOiBudW1iZXI9MCk6IG51bWJlciB7XG4gIHJldHVybiBuPDA/IHg8PDMyK24gfCB4Pj4+LW4gOiB4PDxuIHwgeD4+MzItbjtcbn1cblxuXG4vKipcbiAqIFJldmVyc2UgYWxsIGJpdHMuXG4gKiBAcGFyYW0geCBhbiBpbnQzMlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmV2ZXJzZSh4OiBudW1iZXIpOiBudW1iZXIge1xuICB4ID0gKCh4Pj4+MSkgJiAweDU1NTU1NTU1KSB8ICgoeCAmIDB4NTU1NTU1NTUpPDwxKTtcbiAgeCA9ICgoeD4+PjIpICYgMHgzMzMzMzMzMykgfCAoKHggJiAweDMzMzMzMzMzKTw8Mik7XG4gIHggPSAoKHg+Pj40KSAmIDB4MEYwRjBGMEYpIHwgKCh4ICYgMHgwRjBGMEYwRik8PDQpO1xuICB4ID0gKCh4Pj4+OCkgJiAweDAwRkYwMEZGKSB8ICgoeCAmIDB4MDBGRjAwRkYpPDw4KTtcbiAgcmV0dXJuICh4Pj4+MTYpIHwgKHg8PDE2KTtcbn1cblxuXG4vKipcbiAqIE1lcmdlIGJpdHMgYXMgcGVyIG1hc2suXG4gKiBAcGFyYW0geCBmaXJzdCBpbnQzMlxuICogQHBhcmFtIHkgc2Vjb25kIGludDMyXG4gKiBAcGFyYW0gbSBiaXQgbWFzayAoMCDih5IgZnJvbSB4KVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2UoeDogbnVtYmVyLCB5OiBudW1iZXIsIG06IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiB4IF4gKCh4XnkpICYgbSk7XG59XG5cblxuLyoqXG4gKiBJbnRlcmxlYXZlIGJpdHMgb2YgdHdvIGludDE2cy5cbiAqIEBwYXJhbSB4IGZpcnN0IGludDE2XG4gKiBAcGFyYW0geSBzZWNvbmQgaW50MTZcbiAqIEByZXR1cm5zIGludDMyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnRlcmxlYXZlKHg6IG51bWJlciwgeTogbnVtYmVyKTogbnVtYmVyIHtcbiAgeCA9ICh4IHwgKHg8PDgpKSAmIDB4MDBGRjAwRkY7XG4gIHggPSAoeCB8ICh4PDw0KSkgJiAweDBGMEYwRjBGO1xuICB4ID0gKHggfCAoeDw8MikpICYgMHgzMzMzMzMzMztcbiAgeCA9ICh4IHwgKHg8PDEpKSAmIDB4NTU1NTU1NTU7XG4gIHkgPSAoeSB8ICh5PDw4KSkgJiAweDAwRkYwMEZGO1xuICB5ID0gKHkgfCAoeTw8NCkpICYgMHgwRjBGMEYwRjtcbiAgeSA9ICh5IHwgKHk8PDIpKSAmIDB4MzMzMzMzMzM7XG4gIHkgPSAoeSB8ICh5PDwxKSkgJiAweDU1NTU1NTU1O1xuICByZXR1cm4geSB8ICh4PDwxKTtcbn1cblxuXG4vKipcbiAqIFNpZ24gZXh0ZW5kIHZhcmlhYmxlIGJpdC13aWR0aCBpbnRlZ2VyLlxuICogQHBhcmFtIHggdmFyaWFibGUgYml0LXdpZHRoIGludGVnZXJcbiAqIEBwYXJhbSB3IGJpdCB3aWR0aCAoMzIpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzaWduRXh0ZW5kKHg6IG51bWJlciwgdzogbnVtYmVyPTMyKTogbnVtYmVyIHtcbiAgdyA9IDMyLXc7XG4gIHJldHVybiAoeDw8dyk+Pnc7XG59XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsVUFBVTtBQUNWLFVBQVU7QUFFVixrREFBa0Q7QUFDbEQsU0FBUyxLQUFLLENBQVM7RUFDckIsT0FBTyxDQUFDLEtBQUcsQ0FBQyxJQUFJO0FBQ2xCO0FBR0E7Ozs7O0NBS0MsR0FDRCxPQUFPLFNBQVMsSUFBSSxDQUFTLEVBQUUsQ0FBUyxFQUFFLElBQVUsQ0FBQztFQUNuRCxPQUFPLEFBQUMsTUFBSSxJQUFLLEtBQUs7QUFDeEI7QUFHQTs7OztDQUlDLEdBQ0QsT0FBTyxTQUFTLE1BQU0sQ0FBUyxFQUFFLENBQVM7RUFDeEMsT0FBTyxJQUFJO0FBQ2I7QUFHQTs7Ozs7O0NBTUMsR0FDRCxPQUFPLFNBQVMsSUFBSSxDQUFTLEVBQUUsQ0FBUyxFQUFFLElBQVUsQ0FBQyxFQUFFLElBQVUsQ0FBQztFQUNoRSxPQUFPLEFBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxNQUFJLENBQUMsSUFBTSxLQUFHO0FBQ25DO0FBR0E7Ozs7O0NBS0MsR0FDRCxPQUFPLFNBQVMsTUFBTSxDQUFTLEVBQUUsQ0FBUyxFQUFFLElBQVUsQ0FBQztFQUNyRCxPQUFPLEFBQUMsSUFBSSxDQUFDLElBQU0sQ0FBQyxJQUFJO0FBQzFCO0FBR0E7Ozs7O0NBS0MsR0FDRCxPQUFPLFNBQVMsT0FBTyxDQUFTLEVBQUUsQ0FBUyxFQUFFLElBQVUsQ0FBQztFQUN0RCxPQUFPLElBQUss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