Use Rust to compute 32-bit signed integers and wrap around at the boundary.
Node.js 24 or later and Rust 1.88.0 or later are required. Install Rust with rustup and the native linker for your platform (a C compiler on Linux/macOS or the MSVC build tools on Windows).
npm install int32Installation compiles the native module from source using the included Cargo.lock. Allow the int32 install script if your package manager blocks dependency build scripts, then rebuild the package.
Version 6 raises the minimum Node.js and Rust versions. The ten exported function names and their signed 32-bit results remain the same.
All arguments are converted to signed 32-bit integers by Node-API before the operation. Fractional parts are truncated toward zero, and values outside the signed 32-bit range use their low 32 bits. NaN and infinities become zero. JavaScript numbers outside the safe integer range may already have lost precision before conversion.
Arithmetic wraps around the signed 32-bit range from -2147483648 to 2147483647. Division rounds toward zero, and divide(-2147483648, -1) returns -2147483648. A divisor that becomes zero after conversion throws a RangeError with the message the divisor must not be zero.
Exponents, shift counts, and rotation counts must be nonnegative after conversion; otherwise, a RangeError is thrown. Shift and rotation counts use their low five bits, so a count of 32 acts like zero.
shiftRightUnsigned fills the high bits with zeros but still returns a signed 32-bit integer. For example, shiftRightUnsigned(-1, 0) and shiftRightUnsigned(-1, 32) both return -1, while shiftRightUnsigned(-1, 1) returns 2147483647.
import { add } from "int32";
const n = add(1, 2); // 3import { subtract } from "int32";
const n = subtract(1, 2); // -1import { multiply } from "int32";
const n = multiply(2, 6); // 12import { divide } from "int32";
const n = divide(6, 4); // 1import { pow } from "int32";
const n = pow(2, 3); // 8import { shiftLeft } from "int32";
const n = shiftLeft(5, 2); // 20import { shiftRight } from "int32";
const n1 = shiftRight(5, 2); // 1
const n2 = shiftRight(6, 1); // 3
const n3 = shiftRight(-5, 1); // -3import { shiftRightUnsigned } from "int32";
const n = shiftRightUnsigned(-5, 1); // 2147483645import { rotateLeft } from "int32";
const n = rotateLeft(0b10000000000000000000000100000000, 1); // 0b00000000000000000000001000000001import { rotateRight } from "int32";
const n = rotateRight(0b00000000000000000000000100000001, 8); // 0b00000001000000000000000000000001pnpm install --frozen-lockfile
npm run build
npm run check
npm testThe build generates the native module in native/ and the JavaScript entry point and type declarations in lib/. Tests use the Node.js test runner through tsx. npm run build:watch watches TypeScript files; rebuild after changing Rust files.
cargo +nightly fmt
cargo clippy --locked --all-targets --all-features -- -D warnings
cargo test --locked
cargo +1.88.0 test --lib --bins --locked