mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-21 05:50:55 +08:00
102 lines
2.2 KiB
TypeScript
102 lines
2.2 KiB
TypeScript
// Bitwise operators with JS ToInt32/ToUint32 semantics: a table of edge
|
|
// doubles through every operator vs Node — NaN/±Infinity → 0, truncation
|
|
// toward zero, modular wrap at 2^32, 5-bit shift masks, >>> as Uint32.
|
|
|
|
const nan = 0 / 0;
|
|
const inf = 1 / 0;
|
|
const edges: number[] = [
|
|
0,
|
|
-0,
|
|
1,
|
|
-1,
|
|
5,
|
|
-5,
|
|
3.7,
|
|
-3.7,
|
|
0.5,
|
|
-0.5,
|
|
31,
|
|
32,
|
|
33,
|
|
255,
|
|
256,
|
|
65535,
|
|
2147483647, // 2^31 - 1: INT32_MAX
|
|
2147483648, // 2^31: wraps negative
|
|
2147483649,
|
|
-2147483648, // INT32_MIN
|
|
-2147483649, // wraps positive
|
|
4294967295, // 2^32 - 1
|
|
4294967296, // 2^32: wraps to 0
|
|
4294967297,
|
|
8589934592, // 2^33
|
|
9007199254740991, // 2^53 - 1
|
|
-9007199254740991,
|
|
1e21,
|
|
-1e21,
|
|
1e-7,
|
|
nan,
|
|
inf,
|
|
-inf,
|
|
];
|
|
|
|
for (const a of edges) {
|
|
console.log("~", a, "=>", ~a);
|
|
console.log("self", a, "=>", a & a, a | a, a ^ a, a >>> 0);
|
|
}
|
|
|
|
const rhs: number[] = [0, 1, 3, 16, 31, 32, 33, 63, -1, -31, 0.9, nan, inf, -inf, 2147483648];
|
|
for (const a of edges) {
|
|
for (const b of rhs) {
|
|
console.log(a, "&", b, "=>", a & b);
|
|
console.log(a, "|", b, "=>", a | b);
|
|
console.log(a, "^", b, "=>", a ^ b);
|
|
console.log(a, "<<", b, "=>", a << b);
|
|
console.log(a, ">>", b, "=>", a >> b);
|
|
console.log(a, ">>>", b, "=>", a >>> b);
|
|
}
|
|
}
|
|
|
|
// precedence and mixing with arithmetic
|
|
console.log((1 + 2) & 3, (1 & 2) + 3, 5 & (3 | 8), (5 & 3) | 8);
|
|
console.log(~~3.7, ~~-3.7, ~~nan); // the classic double-not truncation
|
|
|
|
// compound assignments
|
|
let acc = 0xf0f0;
|
|
acc &= 0xff00;
|
|
console.log(acc);
|
|
acc |= 0x000f;
|
|
console.log(acc);
|
|
acc ^= 0xffff;
|
|
console.log(acc);
|
|
acc <<= 4;
|
|
console.log(acc);
|
|
acc >>= 2;
|
|
console.log(acc);
|
|
let wrap = -1;
|
|
wrap >>>= 0;
|
|
console.log(wrap);
|
|
let frac = 3.99;
|
|
frac |= 0;
|
|
console.log(frac);
|
|
|
|
// compound on record fields
|
|
interface Flags {
|
|
bits: number;
|
|
}
|
|
const f: Flags = { bits: 0b1010 };
|
|
f.bits &= 0b0110;
|
|
console.log(f.bits);
|
|
f.bits <<= 3;
|
|
console.log(f.bits);
|
|
|
|
// hash-style loop: the FNV-ish pattern real code uses
|
|
function hashCode(s: string): number {
|
|
let h = 0;
|
|
for (let i = 0; i < s.length; i++) {
|
|
h = ((h << 5) - h + s.charCodeAt(i)) | 0;
|
|
}
|
|
return h;
|
|
}
|
|
console.log(hashCode(""), hashCode("a"), hashCode("hello world"), hashCode("scriptc ⚙️"));
|