Repro
const a: bigint = 0xCBF29CE484222325n;
const b = a ^ 5n;
console.log('a ^ 5n = ' + b.toString(16));
console.log('expected: cbf29ce484222320');
const mask = 0xFFFFFFFFFFFFFFFFn;
const c = (a * 0x100000001B3n) & mask;
console.log('(a * prime) & mask64 = ' + c.toString(16));
console.log('expected: bf9a804f79c4bcb7');
Expected
a ^ 5n = cbf29ce484222320
(a * prime) & mask64 = bf9a804f79c4bcb7
Actual (Perry 0.5.30)
a ^ 5n = -6
(a * prime) & mask64 = 0
Notes
XOR gives a small signed integer instead of flipping the low bits. AND-masking with 0xFFFFFFFFFFFFFFFFn collapses the value to zero. Multiplying and masking produces 0.
This makes any straightforward FNV-1a-64 / MurmurHash / xxhash-64 implementation unusable in user TS — they all rely on mul-then-mask-64 and xor with byte values. I ran into this while trying to get the three implementations (Rust / Zig / Perry) in the honest_bench benchmark to agree on a hash; switching every language to FNV-1a-32 with hand-rolled Math.imul-equivalent multiplication was the workaround.
Likely related to v0.5.24 ("bigint arithmetic + BigInt() coercion") having covered the numeric dispatch paths but not the bitwise ops.
Minimal repro file
See /tmp/perry_repros/C_bigint_bitops.ts (single-file, zero imports).
Repro
Expected
Actual (Perry 0.5.30)
Notes
XOR gives a small signed integer instead of flipping the low bits. AND-masking with
0xFFFFFFFFFFFFFFFFncollapses the value to zero. Multiplying and masking produces 0.This makes any straightforward FNV-1a-64 / MurmurHash / xxhash-64 implementation unusable in user TS — they all rely on mul-then-mask-64 and xor with byte values. I ran into this while trying to get the three implementations (Rust / Zig / Perry) in the
honest_benchbenchmark to agree on a hash; switching every language to FNV-1a-32 with hand-rolledMath.imul-equivalent multiplication was the workaround.Likely related to v0.5.24 ("bigint arithmetic + BigInt() coercion") having covered the numeric dispatch paths but not the bitwise ops.
Minimal repro file
See
/tmp/perry_repros/C_bigint_bitops.ts(single-file, zero imports).