@thi.ng/binary
Advanced tools
Comparing version 3.3.40 to 3.4.0
18
align.js
@@ -1,12 +0,6 @@ | ||
/** | ||
* Aligns `addr` to next multiple of `size`. The latter must be a power | ||
* of 2. | ||
* | ||
* @param addr - value to align | ||
* @param size - alignment value | ||
*/ | ||
export const align = (addr, size) => (size--, (addr + size) & ~size); | ||
/** | ||
* Returns true if `addr` is aligned to wordsize `size`. | ||
*/ | ||
export const isAligned = (addr, size) => !(addr & (size - 1)); | ||
const align = (addr, size) => (size--, addr + size & ~size); | ||
const isAligned = (addr, size) => !(addr & size - 1); | ||
export { | ||
align, | ||
isAligned | ||
}; |
53
bytes.js
import { floatToUintBits, floatToUintBits64 } from "./float.js"; | ||
export const bytes16 = (x, le = false) => { | ||
const b0 = x & 0xff; | ||
const b1 = (x >> 8) & 0xff; | ||
return le ? [b0, b1] : [b1, b0]; | ||
const bytes16 = (x, le = false) => { | ||
const b0 = x & 255; | ||
const b1 = x >> 8 & 255; | ||
return le ? [b0, b1] : [b1, b0]; | ||
}; | ||
export const bytes24 = (x, le = false) => { | ||
const b0 = x & 0xff; | ||
const b1 = (x >> 8) & 0xff; | ||
const b2 = (x >> 16) & 0xff; | ||
return le ? [b0, b1, b2] : [b2, b1, b0]; | ||
const bytes24 = (x, le = false) => { | ||
const b0 = x & 255; | ||
const b1 = x >> 8 & 255; | ||
const b2 = x >> 16 & 255; | ||
return le ? [b0, b1, b2] : [b2, b1, b0]; | ||
}; | ||
export const bytes32 = (x, le = false) => { | ||
const b0 = x & 0xff; | ||
const b1 = (x >> 8) & 0xff; | ||
const b2 = (x >> 16) & 0xff; | ||
const b3 = (x >> 24) & 0xff; | ||
return le ? [b0, b1, b2, b3] : [b3, b2, b1, b0]; | ||
const bytes32 = (x, le = false) => { | ||
const b0 = x & 255; | ||
const b1 = x >> 8 & 255; | ||
const b2 = x >> 16 & 255; | ||
const b3 = x >> 24 & 255; | ||
return le ? [b0, b1, b2, b3] : [b3, b2, b1, b0]; | ||
}; | ||
export const bytes64 = (hi, lo, le = false) => { | ||
return le | ||
? bytes32(lo, le).concat(bytes32(hi, le)) | ||
: bytes32(hi, le).concat(bytes32(lo, le)); | ||
const bytes64 = (hi, lo, le = false) => { | ||
return le ? bytes32(lo, le).concat(bytes32(hi, le)) : bytes32(hi, le).concat(bytes32(lo, le)); | ||
}; | ||
export const bytesF32 = (x, le = false) => bytes32(floatToUintBits(x), le); | ||
export const bytesF64 = (x, le = false) => | ||
//@ts-ignore | ||
bytes64(...floatToUintBits64(x), le); | ||
const bytesF32 = (x, le = false) => bytes32(floatToUintBits(x), le); | ||
const bytesF64 = (x, le = false) => ( | ||
//@ts-ignore | ||
bytes64(...floatToUintBits64(x), le) | ||
); | ||
export { | ||
bytes16, | ||
bytes24, | ||
bytes32, | ||
bytes64, | ||
bytesF32, | ||
bytesF64 | ||
}; |
# Change Log | ||
- **Last updated**: 2023-12-09T19:12:03Z | ||
- **Last updated**: 2023-12-11T10:07:09Z | ||
- **Generator**: [thi.ng/monopub](https://thi.ng/monopub) | ||
@@ -12,2 +12,13 @@ | ||
## [3.4.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/binary@3.4.0) (2023-12-11) | ||
#### 🚀 Features | ||
- add signed/unsigned int conversions ([9f23ae6](https://github.com/thi-ng/umbrella/commit/9f23ae6)) | ||
#### 🩹 Bug fixes | ||
- update precision for float/uint conversions (both ways) ([5289c40](https://github.com/thi-ng/umbrella/commit/5289c40)) | ||
- add tests | ||
### [3.3.36](https://github.com/thi-ng/umbrella/tree/@thi.ng/binary@3.3.36) (2023-11-09) | ||
@@ -14,0 +25,0 @@ |
@@ -1,14 +0,11 @@ | ||
const defBits = (n) => new Array(n).fill(0).map((_, i) => 1 << (n - 1 - i)); | ||
/** | ||
* 8bit values in MSB order (i.e. MSB_BITS[0] = 0x80) | ||
*/ | ||
export const MSB_BITS8 = defBits(8); | ||
/** | ||
* 16bit values in MSB order (i.e. MSB_BITS[0] = 0x8000) | ||
*/ | ||
export const MSB_BITS16 = defBits(16); | ||
/** | ||
* 32bit values in MSB order (i.e. MSB_BITS[0] = 0x80000000) | ||
*/ | ||
export const MSB_BITS32 = defBits(32); | ||
export const MASKS = new Array(33).fill(0).map((_, i) => Math.pow(2, i) - 1); | ||
const defBits = (n) => new Array(n).fill(0).map((_, i) => 1 << n - 1 - i); | ||
const MSB_BITS8 = defBits(8); | ||
const MSB_BITS16 = defBits(16); | ||
const MSB_BITS32 = defBits(32); | ||
const MASKS = new Array(33).fill(0).map((_, i) => Math.pow(2, i) - 1); | ||
export { | ||
MASKS, | ||
MSB_BITS16, | ||
MSB_BITS32, | ||
MSB_BITS8 | ||
}; |
85
count.js
@@ -1,58 +0,31 @@ | ||
/** | ||
* Returns number of 1 bits in `x`. | ||
* | ||
* @param x - | ||
*/ | ||
export const popCount = (x) => ((x = x - ((x >>> 1) & 0x55555555)), | ||
(x = (x & 0x33333333) + ((x >>> 2) & 0x33333333)), | ||
(((x + (x >>> 4)) & 0xf0f0f0f) * 0x1010101) >>> 24); | ||
/** | ||
* Returns number of set bits (1's) in the given array (index range). | ||
* | ||
* @param data - | ||
* @param start - | ||
* @param n - | ||
*/ | ||
export const popCountArray = (data, start = 0, n = data.length) => { | ||
let num = 0; | ||
for (let end = start + n; start < end; start++) { | ||
const x = data[start]; | ||
x > 0 && (num += popCount(x)); | ||
} | ||
return num; | ||
const popCount = (x) => (x = x - (x >>> 1 & 1431655765), x = (x & 858993459) + (x >>> 2 & 858993459), (x + (x >>> 4) & 252645135) * 16843009 >>> 24); | ||
const popCountArray = (data, start = 0, n = data.length) => { | ||
let num = 0; | ||
for (let end = start + n; start < end; start++) { | ||
const x = data[start]; | ||
x > 0 && (num += popCount(x)); | ||
} | ||
return num; | ||
}; | ||
/** | ||
* Returns number of bit changes between `x` and `y`. | ||
* | ||
* https://en.wikipedia.org/wiki/Hamming_distance | ||
* | ||
* @param x - | ||
* @param y - | ||
*/ | ||
export const hammingDist = (x, y) => popCount(x ^ y); | ||
/** | ||
* Math.clz32() polyfill (corrected). | ||
* | ||
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32$revision/1426816 | ||
* | ||
* @param x - | ||
*/ | ||
export const clz32 = (x) => x !== 0 ? 31 - ((Math.log(x >>> 0) / Math.LN2) | 0) : 32; | ||
export const ctz32 = (x) => { | ||
let c = 32; | ||
x &= -x; | ||
x && c--; | ||
x & 0x0000ffff && (c -= 16); | ||
x & 0x00ff00ff && (c -= 8); | ||
x & 0x0f0f0f0f && (c -= 4); | ||
x & 0x33333333 && (c -= 2); | ||
x & 0x55555555 && (c -= 1); | ||
return c; | ||
const hammingDist = (x, y) => popCount(x ^ y); | ||
const clz32 = (x) => x !== 0 ? 31 - (Math.log(x >>> 0) / Math.LN2 | 0) : 32; | ||
const ctz32 = (x) => { | ||
let c = 32; | ||
x &= -x; | ||
x && c--; | ||
x & 65535 && (c -= 16); | ||
x & 16711935 && (c -= 8); | ||
x & 252645135 && (c -= 4); | ||
x & 858993459 && (c -= 2); | ||
x & 1431655765 && (c -= 1); | ||
return c; | ||
}; | ||
/** | ||
* Returns the number of bits required to encode `x`. Returns zero if | ||
* `x` <= 1. | ||
* | ||
* @param x - | ||
*/ | ||
export const bitSize = (x) => (x > 1 ? Math.ceil(Math.log2(x)) : 0); | ||
const bitSize = (x) => x > 1 ? Math.ceil(Math.log2(x)) : 0; | ||
export { | ||
bitSize, | ||
clz32, | ||
ctz32, | ||
hammingDist, | ||
popCount, | ||
popCountArray | ||
}; |
39
edit.js
import { defMask } from "./mask.js"; | ||
/** | ||
* Clears bit in given uint `x`. | ||
* | ||
* @param x - value | ||
* @param bit - bit number (0..31) | ||
*/ | ||
export const bitClear = (x, bit) => (x & ~(1 << bit)) >>> 0; | ||
/** | ||
* Toggles bit in given uint `x`. | ||
* | ||
* @param x - value | ||
* @param bit - bit ID | ||
*/ | ||
export const bitFlip = (x, bit) => (x ^ (1 << bit)) >>> 0; | ||
/** | ||
* Sets bit in given uint `x`. | ||
* | ||
* @param x - value | ||
* @param bit - bit number (0..31) | ||
*/ | ||
export const bitSet = (x, bit) => (x | (1 << bit)) >>> 0; | ||
export const bitSetWindow = (x, y, from, to) => { | ||
const m = defMask(from, to); | ||
return (x & ~m) | ((y << (1 << from)) & m); | ||
const bitClear = (x, bit) => (x & ~(1 << bit)) >>> 0; | ||
const bitFlip = (x, bit) => (x ^ 1 << bit) >>> 0; | ||
const bitSet = (x, bit) => (x | 1 << bit) >>> 0; | ||
const bitSetWindow = (x, y, from, to) => { | ||
const m = defMask(from, to); | ||
return x & ~m | y << (1 << from) & m; | ||
}; | ||
export const bitClearWindow = (x, from, to) => x & ~defMask(from, to); | ||
const bitClearWindow = (x, from, to) => x & ~defMask(from, to); | ||
export { | ||
bitClear, | ||
bitClearWindow, | ||
bitFlip, | ||
bitSet, | ||
bitSetWindow | ||
}; |
152
float.js
@@ -6,109 +6,51 @@ const F64 = new Float64Array(1); | ||
const U32 = new Uint32Array(F64.buffer); | ||
/** | ||
* This value is true iff the environment is Little Endian. | ||
*/ | ||
export const IS_LE = ((U32[0] = 1), U8[0] === 1); | ||
export const floatToIntBits = (x) => ((F32[0] = x), I32[0]); | ||
export const floatToUintBits = (x) => ((F32[0] = x), U32[0]); | ||
export const intBitsToFloat = (x) => ((I32[0] = x), F32[0]); | ||
export const uintBitsToFloat = (x) => ((U32[0] = x), F32[0]); | ||
/** | ||
* Returns i32 representation of f64 as [hi, lo] tuple (takes | ||
* environment's Little Endianess into account). | ||
* | ||
* @param x - | ||
*/ | ||
export const floatToIntBits64 = (x) => ((F64[0] = x), IS_LE ? [I32[1], I32[0]] : [I32[0], I32[1]]); | ||
/** | ||
* Returns u32 representation of f64 as [hi, lo] tuple (takes | ||
* environment's Little Endianess into account). | ||
* | ||
* @param x - | ||
*/ | ||
export const floatToUintBits64 = (x) => ((F64[0] = x), IS_LE ? [U32[1], U32[0]] : [U32[0], U32[1]]); | ||
/** | ||
* Reverse op of {@link floatToIntBits64}. | ||
* | ||
* @param hi - | ||
* @param lo - | ||
*/ | ||
export const intBitsToFloat64 = (hi, lo) => { | ||
IS_LE ? ((I32[1] = hi), (I32[0] = lo)) : ((I32[0] = hi), (I32[1] = lo)); | ||
return F64[0]; | ||
const IS_LE = (U32[0] = 1, U8[0] === 1); | ||
const floatToIntBits = (x) => (F32[0] = x, I32[0]); | ||
const floatToUintBits = (x) => (F32[0] = x, U32[0]); | ||
const intBitsToFloat = (x) => (I32[0] = x, F32[0]); | ||
const uintBitsToFloat = (x) => (U32[0] = x, F32[0]); | ||
const floatToIntBits64 = (x) => (F64[0] = x, IS_LE ? [I32[1], I32[0]] : [I32[0], I32[1]]); | ||
const floatToUintBits64 = (x) => (F64[0] = x, IS_LE ? [U32[1], U32[0]] : [U32[0], U32[1]]); | ||
const intBitsToFloat64 = (hi, lo) => { | ||
IS_LE ? (I32[1] = hi, I32[0] = lo) : (I32[0] = hi, I32[1] = lo); | ||
return F64[0]; | ||
}; | ||
/** | ||
* Reverse op of {@link floatToUintBits64}. | ||
* | ||
* @param hi - | ||
* @param lo - | ||
*/ | ||
export const uintBitsToFloat64 = (hi, lo) => { | ||
IS_LE ? ((U32[1] = hi), (U32[0] = lo)) : ((U32[0] = hi), (U32[1] = lo)); | ||
return F64[0]; | ||
const uintBitsToFloat64 = (hi, lo) => { | ||
IS_LE ? (U32[1] = hi, U32[0] = lo) : (U32[0] = hi, U32[1] = lo); | ||
return F64[0]; | ||
}; | ||
/** | ||
* Converts given float (f32) into a sortable integer representation, using raw | ||
* bitwise conversion via {@link floatToIntBits}. | ||
* | ||
* @remarks | ||
* References: | ||
* - https://github.com/tzaeschke/phtree/blob/develop/PhTreeRevisited.pdf (page | ||
* 3) | ||
* | ||
* @param x - value to convert | ||
*/ | ||
export const floatToSortableInt = (x) => { | ||
if (x === -0) | ||
x = 0; | ||
const i = floatToIntBits(x); | ||
return x < 0 ? ~i | (1 << 31) : i; | ||
const floatToSortableInt = (x) => { | ||
if (x === -0) | ||
x = 0; | ||
const i = floatToIntBits(x); | ||
return x < 0 ? ~i | 1 << 31 : i; | ||
}; | ||
const clamp11 = (x) => (x < -1 ? -1 : x > 1 ? 1 : x); | ||
/** | ||
* Converts normalized float ([-1..1] range) to u8. | ||
* | ||
* @param x - | ||
*/ | ||
export const f32u8 = (x) => (clamp11(x) * 0x7f) & 0xff; | ||
/** | ||
* Converts normalized float ([-1..1] range) to u16. | ||
* | ||
* @param x - | ||
*/ | ||
export const f32u16 = (x) => (clamp11(x) * 0x7fff) & 0xffff; | ||
/** | ||
* Converts normalized float ([-1..1] range) to u24. | ||
* | ||
* @param x - | ||
*/ | ||
export const f32u24 = (x) => (clamp11(x) * 0x7fffff) & 0xffffff; | ||
/** | ||
* Converts normalized float ([-1..1] range) to u32. | ||
* | ||
* @param x - | ||
*/ | ||
export const f32u32 = (x) => (clamp11(x) * 0x7fffffff) >>> 0; | ||
/** | ||
* Reverse op of {@link f32u8}. | ||
* | ||
* @param x - | ||
*/ | ||
export const u8f32 = (x) => ((x &= 0xff), (x | ((x >> 7) * 0xffffff00)) / 0x7f); | ||
/** | ||
* Reverse op of {@link f32u16}. | ||
* | ||
* @param x - | ||
*/ | ||
export const u16f32 = (x) => ((x &= 0xffff), (x | ((x >> 15) * 0xffff0000)) / 0x7fff); | ||
/** | ||
* Reverse op of {@link f32u24}. | ||
* | ||
* @param x - | ||
*/ | ||
export const u24f32 = (x) => ((x &= 0xffffff), (x | ((x >> 23) * 0xff000000)) / 0x7fffff); | ||
/** | ||
* Reverse op of {@link f32u32}. | ||
* | ||
* @param x - | ||
*/ | ||
export const u32f32 = (x) => (x | 0) / 0x7fffffff; | ||
const __f2u = (x, n, p) => x < 0 ? x < -1 ? n : x * n : x > 1 ? p : x * p; | ||
const f32u8 = (x) => __f2u(x, 128, 127) & 255; | ||
const f32u16 = (x) => __f2u(x, 32768, 32767) & 65535; | ||
const f32u24 = (x) => __f2u(x, 8388608, 8388607) & 16777215; | ||
const f32u32 = (x) => __f2u(x, 2147483648, 2147483647) >>> 0; | ||
const u8f32 = (x) => (x &= 255, (x | (x >> 7) * 4294967040) / (127 + (x >> 7))); | ||
const u16f32 = (x) => (x &= 65535, (x | (x >> 15) * 4294901760) / (32767 + (x >> 15))); | ||
const u24f32 = (x) => (x &= 16777215, (x | (x >> 23) * 4278190080) / (8388607 + (x >> 23))); | ||
const u32f32 = (x) => (x | 0) / (2147483647 + (x >>> 31)); | ||
export { | ||
IS_LE, | ||
f32u16, | ||
f32u24, | ||
f32u32, | ||
f32u8, | ||
floatToIntBits, | ||
floatToIntBits64, | ||
floatToSortableInt, | ||
floatToUintBits, | ||
floatToUintBits64, | ||
intBitsToFloat, | ||
intBitsToFloat64, | ||
u16f32, | ||
u24f32, | ||
u32f32, | ||
u8f32, | ||
uintBitsToFloat, | ||
uintBitsToFloat64 | ||
}; |
38
gray.js
@@ -1,27 +0,13 @@ | ||
/** | ||
* Converts 32bit unsigned int to Gray code (reflected binary). Gray codes of | ||
* successive values always have a Hamming distance of 1 (i.e. only 1 bit | ||
* changes at a time). | ||
* | ||
* @remarks | ||
* Reference: | ||
* - https://en.wikipedia.org/wiki/Gray_code | ||
* | ||
* @param x - u32 | ||
*/ | ||
export const encodeGray32 = (x) => (x ^ (x >>> 1)) >>> 0; | ||
/** | ||
* Converts 32bit Gray code to binary / unsigned int. | ||
* | ||
* @remarks | ||
* Reference: | ||
* - https://en.wikipedia.org/wiki/Gray_code | ||
*/ | ||
export const decodeGray32 = (x) => { | ||
x = x ^ (x >>> 16); | ||
x = x ^ (x >>> 8); | ||
x = x ^ (x >>> 4); | ||
x = x ^ (x >>> 2); | ||
x = x ^ (x >>> 1); | ||
return x >>> 0; | ||
const encodeGray32 = (x) => (x ^ x >>> 1) >>> 0; | ||
const decodeGray32 = (x) => { | ||
x = x ^ x >>> 16; | ||
x = x ^ x >>> 8; | ||
x = x ^ x >>> 4; | ||
x = x ^ x >>> 2; | ||
x = x ^ x >>> 1; | ||
return x >>> 0; | ||
}; | ||
export { | ||
decodeGray32, | ||
encodeGray32 | ||
}; |
@@ -9,2 +9,3 @@ export * from "./align.js"; | ||
export * from "./gray.js"; | ||
export * from "./int.js"; | ||
export * from "./logic.js"; | ||
@@ -11,0 +12,0 @@ export * from "./mask.js"; |
@@ -9,2 +9,3 @@ export * from "./align.js"; | ||
export * from "./gray.js"; | ||
export * from "./int.js"; | ||
export * from "./logic.js"; | ||
@@ -11,0 +12,0 @@ export * from "./mask.js"; |
94
logic.js
import { maskL } from "./mask.js"; | ||
export const bitNot = (x) => ~x; | ||
export const bitAnd = (a, b) => a & b; | ||
export const bitNand = (a, b) => ~(a & b); | ||
export const bitOr = (a, b) => a | b; | ||
export const bitNor = (a, b) => ~(a | b); | ||
export const bitXor = (a, b) => a ^ b; | ||
export const bitXnor = (a, b) => ~(a ^ b); | ||
export const bitImply = (a, b) => ~a | b; | ||
export const bitAoi21 = (a, b, c) => ~(a | (b & c)); | ||
export const bitOai21 = (a, b, c) => ~(a & (b | c)); | ||
export const bitAoi22 = (a, b, c, d) => ~((a & b) | (c & d)); | ||
export const bitOai22 = (a, b, c, d) => ~((a | b) & (c | d)); | ||
export const bitMux = (a, b, s) => ((a & ~s) | (b & s)) >>> 0; | ||
export const bitDemux = (a, b, s) => [ | ||
(a & ~s) >>> 0, | ||
(b & s) >>> 0, | ||
const bitNot = (x) => ~x; | ||
const bitAnd = (a, b) => a & b; | ||
const bitNand = (a, b) => ~(a & b); | ||
const bitOr = (a, b) => a | b; | ||
const bitNor = (a, b) => ~(a | b); | ||
const bitXor = (a, b) => a ^ b; | ||
const bitXnor = (a, b) => ~(a ^ b); | ||
const bitImply = (a, b) => ~a | b; | ||
const bitAoi21 = (a, b, c) => ~(a | b & c); | ||
const bitOai21 = (a, b, c) => ~(a & (b | c)); | ||
const bitAoi22 = (a, b, c, d) => ~(a & b | c & d); | ||
const bitOai22 = (a, b, c, d) => ~((a | b) & (c | d)); | ||
const bitMux = (a, b, s) => (a & ~s | b & s) >>> 0; | ||
const bitDemux = (a, b, s) => [ | ||
(a & ~s) >>> 0, | ||
(b & s) >>> 0 | ||
]; | ||
export const bitNotM = (n, x) => maskL(n, ~x); | ||
export const bitAndM = (n, a, b) => maskL(n, a & b); | ||
export const bitNandM = (n, a, b) => maskL(n, ~(a & b)); | ||
export const bitOrM = (n, a, b) => maskL(n, a | b); | ||
export const bitNorM = (n, a, b) => maskL(n, ~(a | b)); | ||
export const bitXorM = (n, a, b) => maskL(n, a ^ b); | ||
export const bitXnorM = (n, a, b) => maskL(n, ~(a ^ b)); | ||
export const bitImplyM = (n, a, b) => maskL(n, ~a | b); | ||
export const bitAoi21M = (n, a, b, c) => maskL(n, ~(a | (b & c))); | ||
export const bitOai21M = (n, a, b, c) => maskL(n, ~(a & (b | c))); | ||
export const bitAoi22M = (n, a, b, c, d) => maskL(n, ~((a & b) | (c & d))); | ||
export const bitOai22M = (n, a, b, c, d) => maskL(n, ~((a | b) & (c | d))); | ||
export const bitMuxM = (n, a, b, s) => maskL(n, (a & ~s) | (b & s)); | ||
export const bitDemuxM = (n, a, b, s) => [ | ||
maskL(n, a & ~s), | ||
maskL(n, b & s), | ||
const bitNotM = (n, x) => maskL(n, ~x); | ||
const bitAndM = (n, a, b) => maskL(n, a & b); | ||
const bitNandM = (n, a, b) => maskL(n, ~(a & b)); | ||
const bitOrM = (n, a, b) => maskL(n, a | b); | ||
const bitNorM = (n, a, b) => maskL(n, ~(a | b)); | ||
const bitXorM = (n, a, b) => maskL(n, a ^ b); | ||
const bitXnorM = (n, a, b) => maskL(n, ~(a ^ b)); | ||
const bitImplyM = (n, a, b) => maskL(n, ~a | b); | ||
const bitAoi21M = (n, a, b, c) => maskL(n, ~(a | b & c)); | ||
const bitOai21M = (n, a, b, c) => maskL(n, ~(a & (b | c))); | ||
const bitAoi22M = (n, a, b, c, d) => maskL(n, ~(a & b | c & d)); | ||
const bitOai22M = (n, a, b, c, d) => maskL(n, ~((a | b) & (c | d))); | ||
const bitMuxM = (n, a, b, s) => maskL(n, a & ~s | b & s); | ||
const bitDemuxM = (n, a, b, s) => [ | ||
maskL(n, a & ~s), | ||
maskL(n, b & s) | ||
]; | ||
export { | ||
bitAnd, | ||
bitAndM, | ||
bitAoi21, | ||
bitAoi21M, | ||
bitAoi22, | ||
bitAoi22M, | ||
bitDemux, | ||
bitDemuxM, | ||
bitImply, | ||
bitImplyM, | ||
bitMux, | ||
bitMuxM, | ||
bitNand, | ||
bitNandM, | ||
bitNor, | ||
bitNorM, | ||
bitNot, | ||
bitNotM, | ||
bitOai21, | ||
bitOai21M, | ||
bitOai22, | ||
bitOai22M, | ||
bitOr, | ||
bitOrM, | ||
bitXnor, | ||
bitXnorM, | ||
bitXor, | ||
bitXorM | ||
}; |
36
mask.js
import { MASKS } from "./constants.js"; | ||
/** | ||
* Creates bit mask by enabling bit `a` to bit `b-1`, both in range | ||
* 0-32. `b` MUST be >= `a`. | ||
* | ||
* @example | ||
* ```ts | ||
* defMask(1,31).toString(16) // 7ffffffe | ||
* defMask(3,8).toString(16) // f8 | ||
* ``` | ||
* | ||
* @param a - first bit | ||
* @param b - last bit | ||
*/ | ||
export const defMask = (a, b) => (~MASKS[a] & MASKS[b]) >>> 0; | ||
/** | ||
* Returns unsigned version of `x` with only lowest `n` bits. | ||
* | ||
* @param n - number of LSB bits | ||
* @param x - value | ||
*/ | ||
export const maskL = (n, x) => (x & MASKS[n]) >>> 0; | ||
/** | ||
* Returns unsigned version of `x` with only highest `n` bits. | ||
* | ||
* @param n - number of MSB bits | ||
* @param x - value | ||
*/ | ||
export const maskH = (n, x) => (x & ~MASKS[n]) >>> 0; | ||
const defMask = (a, b) => (~MASKS[a] & MASKS[b]) >>> 0; | ||
const maskL = (n, x) => (x & MASKS[n]) >>> 0; | ||
const maskH = (n, x) => (x & ~MASKS[n]) >>> 0; | ||
export { | ||
defMask, | ||
maskH, | ||
maskL | ||
}; |
import { clz32 } from "./count.js"; | ||
/** | ||
* Converts binary `x` to one-hot format. | ||
* | ||
* @remarks | ||
* Reference: https://en.wikipedia.org/wiki/One-hot | ||
* | ||
* @param x - | ||
*/ | ||
export const binaryOneHot = (x) => (1 << x) >>> 0; | ||
/** | ||
* Converts one-hot `x` into binary, i.e. the position of the hot bit. | ||
* | ||
* @remarks | ||
* Reference: https://en.wikipedia.org/wiki/One-hot | ||
* | ||
* @param x - | ||
*/ | ||
export const oneHotBinary = (x) => 31 - clz32(x); | ||
const binaryOneHot = (x) => 1 << x >>> 0; | ||
const oneHotBinary = (x) => 31 - clz32(x); | ||
export { | ||
binaryOneHot, | ||
oneHotBinary | ||
}; |
{ | ||
"name": "@thi.ng/binary", | ||
"version": "3.3.40", | ||
"version": "3.4.0", | ||
"description": "100+ assorted binary / bitwise operations, conversions, utilities, lookup tables", | ||
@@ -27,3 +27,5 @@ "type": "module", | ||
"scripts": { | ||
"build": "yarn clean && tsc --declaration", | ||
"build": "yarn build:esbuild && yarn build:decl", | ||
"build:decl": "tsc --declaration --emitDeclarationOnly", | ||
"build:esbuild": "esbuild --format=esm --platform=neutral --target=es2022 --tsconfig=tsconfig.json --outdir=. src/**/*.ts", | ||
"clean": "rimraf --glob '*.js' '*.d.ts' '*.map' doc", | ||
@@ -37,6 +39,7 @@ "doc": "typedoc --excludePrivate --excludeInternal --out doc src/index.ts", | ||
"dependencies": { | ||
"@thi.ng/api": "^8.9.11" | ||
"@thi.ng/api": "^8.9.12" | ||
}, | ||
"devDependencies": { | ||
"@microsoft/api-extractor": "^7.38.3", | ||
"esbuild": "^0.19.8", | ||
"rimraf": "^5.0.5", | ||
@@ -132,3 +135,3 @@ "tools": "^0.0.1", | ||
}, | ||
"gitHead": "25f2ac8ff795a432a930119661b364d4d93b59a0\n" | ||
"gitHead": "5e7bafedfc3d53bc131469a28de31dd8e5b4a3ff\n" | ||
} |
40
pow.js
@@ -1,20 +0,24 @@ | ||
// http://graphics.stanford.edu/~seander/bithacks.html | ||
export const isPow2 = (x) => !!x && !(x & (x - 1)); | ||
export const ceilPow2 = (x) => { | ||
x += (x === 0); | ||
--x; | ||
x |= x >>> 1; | ||
x |= x >>> 2; | ||
x |= x >>> 4; | ||
x |= x >>> 8; | ||
x |= x >>> 16; | ||
return x + 1; | ||
const isPow2 = (x) => !!x && !(x & x - 1); | ||
const ceilPow2 = (x) => { | ||
x += x === 0; | ||
--x; | ||
x |= x >>> 1; | ||
x |= x >>> 2; | ||
x |= x >>> 4; | ||
x |= x >>> 8; | ||
x |= x >>> 16; | ||
return x + 1; | ||
}; | ||
export const floorPow2 = (x) => { | ||
x |= x >>> 1; | ||
x |= x >>> 2; | ||
x |= x >>> 4; | ||
x |= x >>> 8; | ||
x |= x >>> 16; | ||
return x - (x >>> 1); | ||
const floorPow2 = (x) => { | ||
x |= x >>> 1; | ||
x |= x >>> 2; | ||
x |= x >>> 4; | ||
x |= x >>> 8; | ||
x |= x >>> 16; | ||
return x - (x >>> 1); | ||
}; | ||
export { | ||
ceilPow2, | ||
floorPow2, | ||
isPow2 | ||
}; |
@@ -57,3 +57,3 @@ <!-- This file is generated - DO NOT EDIT! --> | ||
Package sizes (brotli'd, pre-treeshake): ESM: 2.08 KB | ||
Package sizes (brotli'd, pre-treeshake): ESM: 2.19 KB | ||
@@ -60,0 +60,0 @@ ## Dependencies |
@@ -1,22 +0,8 @@ | ||
/** | ||
* Rotates `x` `n` bits to the left. | ||
* | ||
* @param x - value | ||
* @param n - rotation step | ||
*/ | ||
export const rotateLeft = (x, n) => ((x << n) | (x >>> (32 - n))) >>> 0; | ||
/** | ||
* Rotates `x` `n` bits to the right. | ||
* | ||
* @param x - value | ||
* @param n - rotation step | ||
*/ | ||
export const rotateRight = (x, n) => ((x >>> n) | (x << (32 - n))) >>> 0; | ||
/** | ||
* Shifts `x` by `n` bits left or right. If `n` >= 0, the value will be `>>>` | ||
* shifted to right, if `n` < 0 the value will be shifted left. | ||
* | ||
* @param x - | ||
* @param n - | ||
*/ | ||
export const shiftRL = (x, n) => (n < 0 ? x << -n : x >>> n); | ||
const rotateLeft = (x, n) => (x << n | x >>> 32 - n) >>> 0; | ||
const rotateRight = (x, n) => (x >>> n | x << 32 - n) >>> 0; | ||
const shiftRL = (x, n) => n < 0 ? x << -n : x >>> n; | ||
export { | ||
rotateLeft, | ||
rotateRight, | ||
shiftRL | ||
}; |
78
splat.js
@@ -1,58 +0,20 @@ | ||
/** | ||
* Repeats lowest nibble of `x` as 24 bit uint. | ||
* | ||
* @param x - | ||
*/ | ||
export const splat4_24 = (x) => (x & 0xf) * 0x111111; | ||
/** | ||
* Repeats lowest nibble of `x` as 32 bit uint. | ||
* | ||
* @param x - | ||
*/ | ||
export const splat4_32 = (x) => ((x & 0xf) * 0x11111111) >>> 0; | ||
/** | ||
* Repeats lowest byte of `x` as 24 bit uint. | ||
* | ||
* @param x - | ||
*/ | ||
export const splat8_24 = (x) => (x & 0xff) * 0x010101; | ||
/** | ||
* Repeats lowest byte of `x` as 32 bit uint. | ||
* | ||
* @param x - | ||
*/ | ||
export const splat8_32 = (x) => ((x & 0xff) * 0x01010101) >>> 0; | ||
/** | ||
* Repeats lowest 16bit of `x` as 32 bit uint. | ||
* | ||
* @param x - | ||
*/ | ||
export const splat16_32 = (x) => ((x &= 0xffff), ((x << 16) | x) >>> 0); | ||
/** | ||
* Returns true if bits 0-3 are same as bits 4-7. | ||
* | ||
* @param x - | ||
*/ | ||
export const same4 = (x) => ((x >> 4) & 0xf) === (x & 0xf); | ||
/** | ||
* Returns true if bits 0-7 are same as bits 8-15. | ||
* | ||
* @param x - | ||
*/ | ||
export const same8 = (x) => ((x >> 8) & 0xff) === (x & 0xff); | ||
/** | ||
* Expands 3x4bit value like `0xabc` to 24bits: `0xaabbcc` | ||
* | ||
* @param x - | ||
*/ | ||
export const interleave4_12_24 = (x) => ((x & 0xf00) * 0x1100) | ((x & 0xf0) * 0x110) | ((x & 0xf) * 0x11); | ||
/** | ||
* Expands 4x4bit value like `0xabcd` to 32bits: `0xaabbccdd` | ||
* | ||
* @param x - | ||
*/ | ||
export const interleave4_16_32 = (x) => (((x & 0xf000) * 0x11000) | | ||
((x & 0xf00) * 0x1100) | | ||
((x & 0xf0) * 0x110) | | ||
((x & 0xf) * 0x11)) >>> | ||
0; | ||
const splat4_24 = (x) => (x & 15) * 1118481; | ||
const splat4_32 = (x) => (x & 15) * 286331153 >>> 0; | ||
const splat8_24 = (x) => (x & 255) * 65793; | ||
const splat8_32 = (x) => (x & 255) * 16843009 >>> 0; | ||
const splat16_32 = (x) => (x &= 65535, (x << 16 | x) >>> 0); | ||
const same4 = (x) => (x >> 4 & 15) === (x & 15); | ||
const same8 = (x) => (x >> 8 & 255) === (x & 255); | ||
const interleave4_12_24 = (x) => (x & 3840) * 4352 | (x & 240) * 272 | (x & 15) * 17; | ||
const interleave4_16_32 = (x) => ((x & 61440) * 69632 | (x & 3840) * 4352 | (x & 240) * 272 | (x & 15) * 17) >>> 0; | ||
export { | ||
interleave4_12_24, | ||
interleave4_16_32, | ||
same4, | ||
same8, | ||
splat16_32, | ||
splat4_24, | ||
splat4_32, | ||
splat8_24, | ||
splat8_32 | ||
}; |
213
swizzle.js
@@ -1,176 +0,43 @@ | ||
/** | ||
* Extracts 16-bit lane from given 32bit uint and returns as unsigned | ||
* half word [0x0000 .. 0xffff]. | ||
* | ||
* - Lane #0: bits 16-31 | ||
* - Lane #1: bits 0-15 | ||
* | ||
* @param x - | ||
* @param lane - lane ID enum | ||
*/ | ||
export const lane16 = (x, lane) => (x >>> ((1 - lane) << 4)) & 0xffff; | ||
/** | ||
* Extracts 8-bit lane from given 32bit uint and returns as unsigned | ||
* byte [0x00 .. 0xff]. | ||
* | ||
* - Lane #0: bits 24-31 | ||
* - Lane #1: bits 16-23 | ||
* - Lane #2: bits 8-15 | ||
* - Lane #3: bits 0-7 | ||
* | ||
* @param x - | ||
* @param lane - lane ID enum | ||
*/ | ||
export const lane8 = (x, lane) => (x >>> ((3 - lane) << 3)) & 0xff; | ||
/** | ||
* Extracts 4-bit lane from given 32bit uint and returns as unsigned | ||
* nibble [0x00 .. 0x0f]. | ||
* | ||
* - Lane #0: bits 28-31 | ||
* - Lane #1: bits 24-27 | ||
* - Lane #2: bits 20-23 | ||
* - Lane #3: bits 16-19 | ||
* - Lane #4: bits 12-15 | ||
* - Lane #5: bits 8-11 | ||
* - Lane #6: bits 4-7 | ||
* - Lane #7: bits 0-3 | ||
* | ||
* @param x - | ||
* @param lane - lane ID enum | ||
*/ | ||
export const lane4 = (x, lane) => (x >>> ((7 - lane) << 2)) & 0xf; | ||
export const lane2 = (x, lane) => (x >>> ((15 - lane) << 1)) & 0x3; | ||
export const setLane16 = (x, y, lane) => lane ? mux(x, y, 0xffff) : mux(x, y << 16, 0xffff0000); | ||
/** | ||
* Sets 8-bit `lane` with value`y` in `x`. | ||
* | ||
* {@link lane8} | ||
* | ||
* @param x - | ||
* @param y - | ||
* @param lane - lane ID enum | ||
*/ | ||
export const setLane8 = (x, y, lane) => { | ||
const l = (3 - lane) << 3; | ||
return ((~(0xff << l) & x) | ((y & 0xff) << l)) >>> 0; | ||
const lane16 = (x, lane) => x >>> (1 - lane << 4) & 65535; | ||
const lane8 = (x, lane) => x >>> (3 - lane << 3) & 255; | ||
const lane4 = (x, lane) => x >>> (7 - lane << 2) & 15; | ||
const lane2 = (x, lane) => x >>> (15 - lane << 1) & 3; | ||
const setLane16 = (x, y, lane) => lane ? mux(x, y, 65535) : mux(x, y << 16, 4294901760); | ||
const setLane8 = (x, y, lane) => { | ||
const l = 3 - lane << 3; | ||
return (~(255 << l) & x | (y & 255) << l) >>> 0; | ||
}; | ||
/** | ||
* Sets 4-bit `lane` with value `y` in `x`. | ||
* | ||
* {@link lane4} | ||
* | ||
* @param x - | ||
* @param y - | ||
* @param lane - lane ID enum | ||
*/ | ||
export const setLane4 = (x, y, lane) => { | ||
const l = (7 - lane) << 2; | ||
return ((~(0xf << l) & x) | ((y & 0xf) << l)) >>> 0; | ||
const setLane4 = (x, y, lane) => { | ||
const l = 7 - lane << 2; | ||
return (~(15 << l) & x | (y & 15) << l) >>> 0; | ||
}; | ||
/** | ||
* Sets 2-bit `lane` with value `y` in `x`. | ||
* | ||
* {@link lane2} | ||
* | ||
* @param x - | ||
* @param y - | ||
* @param lane - lane ID enum | ||
*/ | ||
export const setLane2 = (x, y, lane) => { | ||
const l = (15 - lane) << 1; | ||
return ((~(0x3 << l) & x) | ((y & 0x3) << l)) >>> 0; | ||
const setLane2 = (x, y, lane) => { | ||
const l = 15 - lane << 1; | ||
return (~(3 << l) & x | (y & 3) << l) >>> 0; | ||
}; | ||
/** | ||
* Re-orders byte lanes in given order (MSB). | ||
* | ||
* @example | ||
* ```ts | ||
* swizzle(0x12345678, 3, 2, 1, 0) // 0x78563412 | ||
* swizzle(0x12345678, 1, 0, 3, 2) // 0x34127856 | ||
* swizzle(0x12345678, 2, 2, 0, 0) // 0x56561212 | ||
* ``` | ||
* | ||
* @param x - value | ||
* @param a - lane ID enum | ||
* @param b - lane ID enum | ||
* @param c - lane ID enum | ||
* @param d - lane ID enum | ||
*/ | ||
export const swizzle8 = (x, a, b, c, d) => ((lane8(x, a) << 24) | | ||
(lane8(x, b) << 16) | | ||
(lane8(x, c) << 8) | | ||
lane8(x, d)) >>> | ||
0; | ||
/** | ||
* | ||
* @param x - value | ||
* @param a - lane ID enum | ||
* @param b - lane ID enum | ||
* @param c - lane ID enum | ||
* @param d - lane ID enum | ||
* @param e - lane ID enum | ||
* @param f - lane ID enum | ||
* @param g - lane ID enum | ||
* @param h - lane ID enum | ||
*/ | ||
export const swizzle4 = (x, a, b, c, d, e, f, g, h) => ((lane4(x, a) << 28) | | ||
(lane4(x, b) << 24) | | ||
(lane4(x, c) << 20) | | ||
(lane4(x, d) << 16) | | ||
(lane4(x, e) << 12) | | ||
(lane4(x, f) << 8) | | ||
(lane4(x, g) << 4) | | ||
lane4(x, h)) >>> | ||
0; | ||
/** | ||
* Merges bits of `a` and `b`, selecting bits from `b` where `mask` bits | ||
* are set. | ||
* | ||
* @example | ||
* ```ts | ||
* mux(0x12345678, 0xaaaa5555, 0xffff0000) | ||
* // 0xaaaa5678 | ||
* | ||
* mux(0x12345678, 0xaaaa5555, 0x0000ffff) | ||
* // 0x12345555 | ||
* ``` | ||
* | ||
* @param a - | ||
* @param b - | ||
* @param mask - | ||
*/ | ||
export const mux = (a, b, mask) => (~mask & a) | (mask & b); | ||
/** | ||
* Same as `swizzle8(x, 3, 2, 1, 0)`, but faster. | ||
* | ||
* @param x - | ||
*/ | ||
export const flip8 = (x) => ((x >>> 24) | ((x >> 8) & 0xff00) | ((x & 0xff00) << 8) | (x << 24)) >>> 0; | ||
/** | ||
* Swaps the highest & lowest 16 bits in `x`. | ||
* | ||
* @example | ||
* ```ts | ||
* flip16(0x12345678) | ||
* // 0x56781234 | ||
* ``` | ||
* | ||
* @param x - | ||
*/ | ||
export const flip16 = (x) => mux(x << 16, x >>> 16, 0xffff); | ||
/** | ||
* @deprecated renamed to {@link flip8} | ||
*/ | ||
export const flipBytes = flip8; | ||
/** | ||
* Swaps bytes lanes 0 & 2 (i.e. bits 24-31 with bits 8-15) | ||
* | ||
* @param x - | ||
*/ | ||
export const swapLane02 = (x) => ((x & 0xff00) << 16) | ((x >>> 16) & 0xff00) | (x & 0x00ff00ff); | ||
/** | ||
* Swaps bytes lanes 1 & 3 (i.e. bits 16-23 with bits 0-7) | ||
* | ||
* @param x - | ||
*/ | ||
export const swapLane13 = (x) => ((x & 0xff) << 16) | ((x >> 16) & 0xff) | (x & 0xff00ff00); | ||
const swizzle8 = (x, a, b, c, d) => (lane8(x, a) << 24 | lane8(x, b) << 16 | lane8(x, c) << 8 | lane8(x, d)) >>> 0; | ||
const swizzle4 = (x, a, b, c, d, e, f, g, h) => (lane4(x, a) << 28 | lane4(x, b) << 24 | lane4(x, c) << 20 | lane4(x, d) << 16 | lane4(x, e) << 12 | lane4(x, f) << 8 | lane4(x, g) << 4 | lane4(x, h)) >>> 0; | ||
const mux = (a, b, mask) => ~mask & a | mask & b; | ||
const flip8 = (x) => (x >>> 24 | x >> 8 & 65280 | (x & 65280) << 8 | x << 24) >>> 0; | ||
const flip16 = (x) => mux(x << 16, x >>> 16, 65535); | ||
const flipBytes = flip8; | ||
const swapLane02 = (x) => (x & 65280) << 16 | x >>> 16 & 65280 | x & 16711935; | ||
const swapLane13 = (x) => (x & 255) << 16 | x >> 16 & 255 | x & 4278255360; | ||
export { | ||
flip16, | ||
flip8, | ||
flipBytes, | ||
lane16, | ||
lane2, | ||
lane4, | ||
lane8, | ||
mux, | ||
setLane16, | ||
setLane2, | ||
setLane4, | ||
setLane8, | ||
swapLane02, | ||
swapLane13, | ||
swizzle4, | ||
swizzle8 | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
38
53209
6
978
Updated@thi.ng/api@^8.9.12