js-cuint
Emulates C-style unsigned 32-bit and 64-bit integer arithmetic in JavaScript, giving hashing and bit-twiddling code overflow-safe math without floating-point rounding.
Repository Health
Technical Analysis
cuint fills a gap that existed in JavaScript before native BigInt: it lets code perform unsigned 32-bit and 64-bit integer arithmetic (add, subtract, multiply, divide, shifts, rotations, and bitwise ops) with correct C-style overflow/truncation behavior, rather than JavaScript’s signed, floating-point-backed number semantics. Each integer is represented internally as a set of 16-bit words (two for UINT32, four for UINT64) so every operation stays within the range where JavaScript’s bitwise operators behave predictably.
The library ships as a small UMD module usable from Node (require('cuint')), AMD loaders, or a plain <script> tag in the browser via prebuilt minified files in build/. It has zero runtime dependencies and was written with performance as the explicit design goal, favoring inlined bit manipulation over object allocation in hot paths like multiply() and div(). It’s most commonly pulled in as a dependency of pure-JS hashing implementations (e.g. MurmurHash and xxHash ports) that need 32/64-bit unsigned arithmetic to match the reference C algorithms exactly.
What You Get
- UINT32 and UINT64 constructors instantiable from low/high bit pairs, a plain number, or a numeric string with a chosen radix
- Full arithmetic set: add, subtract, multiply, and div (with an overflow-safe long-division algorithm that also exposes the remainder)
- Bitwise operations: and, or, xor, not, shiftLeft/shiftRight, and rotateLeft/rotateRight, all mutating in place for chaining
- Comparison helpers (equals/eq, greaterThan/gt, lessThan/lt) and clone() for creating a non-mutated copy before an operation
- Prebuilt minified UMD bundles in build/ for direct <script> inclusion in the browser, alongside the Node/CommonJS entry point
Common Use Cases
- Implementing hash functions (MurmurHash, xxHash, FNV-style algorithms) that require exact unsigned 32/64-bit overflow behavior to match their C reference implementations
- Porting C/C++ checksum, CRC, or bit-manipulation algorithms to JavaScript without rewriting the overflow logic by hand
- Working with binary protocols or file formats that encode unsigned 32/64-bit fields, where JavaScript’s native signed doubles would misrepresent large values
- Building low-level numeric utilities in pre-BigInt codebases or environments where BigInt isn’t available or desirable for performance reasons
Under The Hood
Architecture
cuint is organized as two parallel, independently implemented modules (lib/uint32.js, lib/uint64.js), each wrapped in its own UMD IIFE that registers as an AMD module, a CommonJS export, or a global depending on the environment; index.js simply re-exports both as UINT32/UINT64. Neither module shares a common base class or arithmetic helper — UINT32 splits a value into two 16-bit words (_low/_high) while UINT64 splits into four (_a00/_a16/_a32/_a48), and every method (add, multiply, div, shift, rotate) reimplements its own word-carry logic for that representation. This is a deliberately flat, dependency-free computation module with no I/O and no external state, but it means a change to the core word-splitting strategy would require parallel edits across both files rather than a single shared implementation.
Tech Stack
The runtime has zero dependencies — plain ES5 JavaScript targeting maximum compatibility across Node, AMD loaders, and browsers via the UMD wrapper pattern. The only devDependencies are mocha for testing and a small “minify” package driven by a custom build.js script, wired to run automatically on prepublish to regenerate the minified browser bundles checked into build/. There is no bundler, transpiler, TypeScript, or framework involved anywhere in the toolchain.
Code Quality
Test coverage is extensive at the method level: the test/ directory contains a dedicated spec file per operation per type (e.g. UINT32_add-test.js, UINT64_div-test.js, UINT32_shiftLeft-test.js), run via Mocha with Node’s built-in assert. There is no linter configuration, no CI workflow, and no type annotations anywhere in the repo, so quality enforcement relies entirely on the test suite and manual review. Error handling is minimal and targeted only at truly invalid states (division by zero throws explicitly); most other edge cases are left unguarded, consistent with a small, performance-focused utility rather than a defensively-coded library.
What Makes It Unique cuint isn’t algorithmically novel — it’s one of several userland unsigned-integer emulation libraries that predate JavaScript’s native BigInt (which now solves the same overflow-safety problem at the language level). Its niche is being a lightweight, dependency-free building block that several pure-JS hashing library ports (MurmurHash- and xxHash-style implementations) rely on internally for C-compatible 32/64-bit arithmetic, rather than something end users typically reach for directly.