Skip to content

Floating-point and mask contract

These rules define f32 arithmetic, predicates and canonical masks. For examples, see operations.

Arrays, masks and ownership

  • engine.f32 and arena.f32 provide numeric operations. Predicates return Uint8Array or MaskBuffer; no implicit numeric conversion occurs.
  • engine.mask provides and/or/xor/not/any/all; arena.mask also provides alloc/from. Buffer dtype and ownership are checked at runtime.
  • Every input mask byte must be 0 or 1. Validation covers the entire input, including bytes after an early answer to any/all would be possible.
  • from/set copy their input. toArray returns an independent copy. A destination need not already contain canonical mask bytes unless it is also an input.
  • Empty any returns false; empty all returns true.
  • select(mask, whenTrue, whenFalse, options?) takes its length from the mask. Either or both branches may broadcast a scalar. Array and resident calls use their corresponding input and output objects.
  • Exact same-dtype input/output aliases are allowed. Partial output overlap and any nonempty numeric/mask overlap are rejected before writing. Read-only inputs may overlap.
  • Shared, resizable, detached and foreign-realm arrays are rejected. Empty resident allocations have distinct addresses. A mask uses one byte per element with one-byte alignment.

Numerical rules

OperationBehavior
neg / squareFlip the sign / perform one f32 multiplication
sqrtf32 square root; preserve -0; negative nonzero input produces NaN
reciprocalf32 1 / x, without an approximate reciprocal instruction
signPreserve NaN and ±0; otherwise return ±1
copysignCopy the second operand's sign bit, including signed zero and NaN
floor/ceil/truncRound toward negative infinity, positive infinity or zero; preserve the appropriate zero sign
roundMath.round ties toward positive infinity; compare the fractional part to avoid double rounding through f32(x + 0.5)
roundEvenFixed ties-to-even, independent of the host rounding mode
eq/neNaN gives false/true; +0 and -0 compare equal
lt/le/gt/geNaN participation gives false
isNaN/isFinite/isInf/signbitReturn canonical 0/1; signbit reads the actual sign bit
selectCopy the chosen value without arithmetic on either branch; preserve signed zero

Every basic arithmetic step rounds to f32. Broadcast scalars and clamp bounds are converted to f32 before arithmetic. Division by zero yields infinity or NaN. min/max propagate NaN and preserve signed zero like Math.min/Math.max. Clamp evaluates min(max(input, lower), upper), rejects NaN or reversed bounds, and allows infinite bounds.

Output NaN payloads are unspecified; predicates inspect the actual input values. The Wasm vector implementation of roundEven uses Rust's f32x4_nearest. Basic arithmetic uses separate target-precision steps, with no implicit FMA or fast-math.

Internal ABI

The package uses ABI v6. Dedicated predicate, select, mask and mask-reduction channels do not reuse clamp bounds. JS and binaries must agree on ABI and registry SHA-256.

N-API checks actual TypedArray metadata and byte intervals before entering Rust; its implementation does not create overlapping mutable Rust slices. Wasm accepts only the base address of a live allocation with matching dtype, length and scalar flags. Array-output exports return zero or a positive error code. Mask reductions return 0/1, with negative values reserved for ABI errors. invalidMask = 7; errors must leave the destination unchanged.

SIMD scope

neg/square/sqrt/reciprocal/copysign/floor/ceil/trunc/roundEven have AVX2, NEON and SIMD128 vector prefixes with scalar tails. sign/round, predicates, select and mask operations use scalar kernels and report fallback on SIMD engines. Compiler auto-vectorization does not count as explicit SIMD coverage.

simd: 'required' constrains initialization, not each operation. getCapability('mask.and') defaults to mask; other operations default to f32. See support and compatibility for verified targets and fallback coverage.

Released under the MIT License.