FS FormScript
Package@formscript/decimal
Specification5.6, 5.32
Depends onnothing — it is a leaf

@formscript/decimal

Exact decimal128 arithmetic, per the core-2026.1 profile of §5.6 of the specification.

This package depends on nothing. It is the only place in the repository where arithmetic happens, and the guarantee that 0.1 + 0.2 == 0.3 is true is a guarantee about this package, not about the evaluator that uses it.

The numbers

IEEE 754-2008 decimal128: 34 significant decimal digits, an adjusted exponent in −6143…+6144 inclusive, and round-half-even rounding. The coefficient is a BigInt; there is no floating point anywhere in the package.

Subnormal results are not produced. A result that would require one is an underflow and throws DecimalError, exactly as a result beyond the exponent range does — it is never silently rounded to zero.

Usage

ts
import { Decimal } from '@formscript/decimal';

const a = Decimal.fromString('0.1');
const b = Decimal.fromString('0.2');

a.add(b).toString();      // '0.3'
a.add(b).equals(Decimal.fromString('0.3'));   // true

Beyond the four operations, the package offers floor, ceil, truncate, round(places, mode) ('half_up' or 'half_even'), modTrunc (the truncated remainder of Spec-5.30), pow (integer exponents, Spec-6.33) and the fromParts factory. Every one of them rounds and range-checks exactly as the four operations do, and throws DecimalError on a result outside the profile's range.

The canonical decimal form (§5.32) is the single text by which a number is written: plain positional notation for an adjusted exponent in −6…+20, scientific notation (1E+21, 1.5E+3, 1E-7) otherwise, no trailing fractional zeros, and 0 for zero. toExponentString always uses scientific notation.

Cross-checked

The package's results are cross-checked against Python's decimal module over 800 random cases × 4 operations — 3,200 identical results — including the rounding of ties.

Public API

2 exported symbols.

Decimal class
DecimalError class

Exact decimal128 arithmetic for the `number` type: value = coefficient x 10^exponent. Every operation is bigint-exact; round-half-even to 34 significant digi…