npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

fixed-precision

v1.7.3

Published

A fixed-precision decimal arithmetic library for JavaScript/TypeScript

Readme

FixedPrecision

FixedPrecision is a library for handling fixed‑precision decimal numbers in JavaScript/TypeScript. By storing scaled bigint values internally, this library enables precise arithmetic, detailed control over decimal places, and various rounding modes — ideal for avoiding floating‑point imprecision.

Features

  • Configurable precision — 0 to 20 decimal places.
  • 9 rounding modes — ROUND_UP, ROUND_DOWN, ROUND_CEIL, ROUND_FLOOR, ROUND_HALF_UP, ROUND_HALF_DOWN, ROUND_HALF_EVEN, ROUND_HALF_CEIL, ROUND_HALF_FLOOR.
  • Full arithmetic — addition, subtraction, multiplication, division, modulo, exponentiation, square root, cube root, negation, integer division.
  • Method chaining — arithmetic and comparison directly with number, string, or bigint without explicit instantiation.
  • Flexible conversionstoString, toNumber, toFixed, toExponential, toPrecision, toFormat, toJSON, toBinary, toOctal, toHex.
  • Rounding & scalinground, prec, ceil, floor, trunc, scale, shiftedBy, clamp, toNearest.
  • Comparisonscmp, eq, gt, gte, lt, lte (plus raw variants).
  • PredicatesisZero, isPositive, isNegative, isInteger; logical operations (sign, not, and, or, xor).
  • Logarithmsln, log, log2, log10, exp.
  • Trigonometrysin, cos, tan, sec, csc, cot and their inverse, hyperbolic, and inverse‑hyperbolic counterparts (26 functions total, including atan2).
  • Statisticsmin, max, sum, hypot, random.
  • Math constantsPI, e, phi, sqrt2.
  • Combinatoricsfactorial, permutations, combinations.
  • Vector / matrixdot, cross.
  • Fractionsnum, den, fraction.
  • Bitwise operationsbitAnd, bitOr, bitXor, bitNot, leftShift, rightArithShift.
  • TypeScript — full type definitions included (FixedPrecisionValue, FixedPrecisionConfig, RoundingMode, Comparison).

Installation

npm install fixed-precision

Quick Start

import FixedPrecision, { fixedconfig } from "fixed-precision";

fixedconfig.configure({ places: 8, roundingMode: 4 });

const a = new FixedPrecision("1.2345");
const b = new FixedPrecision(2.3456);

const sum = a.add(b);
console.log(sum.toString()); // "3.5801"

const product = a.mul(b);
console.log(product.toString()); // "2.8955832"

// Method chaining with raw values
const result = new FixedPrecision(10.5).add(5).div(3).toNumber();
console.log(result); // 5.16666667

// Mixed input types
new FixedPrecision(100).add("50").sub(25n).mul(2).div("5").toString(); // "50"

Global Configuration

Set default decimal places and rounding mode for all new FixedPrecision() instances that don't receive an explicit context.

import { fixedconfig } from "fixed-precision";
// or: FixedPrecision.configure({ ... })

fixedconfig.configure({
  places: 8,        // 0–20
  roundingMode: 4,  // ROUND_HALF_UP (default)
});

Rounding Modes

| Code | Name | Behavior | |------|------------------|--------------------------------------------| | 0 | ROUND_UP | Rounds away from zero | | 1 | ROUND_DOWN | Rounds toward zero (truncation) | | 2 | ROUND_CEIL | Rounds toward +Infinity | | 3 | ROUND_FLOOR | Rounds toward -Infinity | | 4 | ROUND_HALF_UP | Rounds half away from zero | | 5 | ROUND_HALF_DOWN | Rounds half toward zero | | 6 | ROUND_HALF_EVEN | Rounds half to the nearest even number | | 7 | ROUND_HALF_CEIL | Rounds half toward +Infinity | | 8 | ROUND_HALF_FLOOR | Rounds half toward -Infinity |

Precision Factories (Recommended)

For applications that need multiple precisions at the same time, use immutable factories instead of mutating the global configuration.

import FixedPrecision, { fixedconfig } from "fixed-precision";

// Independent, immutable contexts
const FP8 = FixedPrecision.create({ places: 8, roundingMode: 4 });
const FP2 = FixedPrecision.create({ places: 2 });

const a = FP8("1.23456789"); // "1.23456789"
const b = FP2("1.23");       // "1.23"

// Method chaining works with factories too
const c = FP8(10.5).add(5).div(3);

// Factories are unaffected by global config changes
fixedconfig.configure({ places: 4 });
FP8("1").toString(false);                // "1.00000000" (unchanged)
FP2("1").toString(false);                // "1.00"       (unchanged)
new FixedPrecision("1").toString(false); // "1.0000"  (global default)

Why factories?

  • Performance — No per‑instance option parsing; the factory captures its scale and rounding mode once.
  • Clarity — The precision is explicit in the factory variable name.
  • Safety — No shared mutable state; cross‑context arithmetic throws an error.
  • Flexibility — Create as many contexts as needed and pass them around.

Factory API

FixedPrecision.create(config: FixedPrecisionConfig): (val: FixedPrecisionValue) => FixedPrecision
  • config.places — integer 0–20 (required).
  • config.roundingMode — integer 0–8 (optional, defaults to 4 / ROUND_HALF_UP).
  • The returned function creates instances locked to that configuration.
  • factory.format exposes the frozen { places, roundingMode } object.

Documentation

For more detailed guides and examples, see the docs/ directory:

| Category | Topics | |----------|--------| | Getting Started | Quick Start, Installation, Basic Concepts | | Core Features | Arithmetic, Raw Operations, Rounding & Scaling, Conversion, Minimal Build | | Configuration | Global Configuration, Precision Factories | | Advanced | Performance, Error Handling, BigInt Warning | | API | Full API Reference, Type Definitions | | Integration | Migration Guide, Integration, Testing |

API Reference

Constructor

new FixedPrecision(value: FixedPrecisionValue, ctx?: FPContext)

Accepts string | number | bigint | FixedPrecision.

  • string / number → parsed as a decimal value and scaled to the current context.
  • bigint → treated as already scaled (pre‑scaled). See BigInt Warning.
  • FixedPrecision → reused directly (validation ensures same precision context).

Arithmetic

All arithmetic methods accept FixedPrecisionValue (string | number | bigint | FixedPrecision).

Scaled operations (maintain decimal precision, validate configuration):

| Instance | Static | Description | |-------------|-----------------------------|--------------------------| | add(v) | FixedPrecision.add(a, b) | Addition | | sub(v) | FixedPrecision.sub(a, b) | Subtraction | | mul(v) | FixedPrecision.mul(a, b) | Multiplication | | div(v) | FixedPrecision.div(a, b) | Division | | mod(v) | FixedPrecision.mod(a, b) | Modulo | | pow(n) | FixedPrecision.pow(v, n) | Exponentiation (integer) | | sqrt() | FixedPrecision.sqrt(v) | Square root | | square() | FixedPrecision.square(v) | Square (value²) | | cube() | FixedPrecision.cube(v) | Cube (value³) | | cbrt() | FixedPrecision.cbrt(v) | Cube root | | neg() | — | Negation (-value) | | abs() | FixedPrecision.abs(v) | Absolute value | | idiv(v) | — | Integer division | | divmod(v) | — | Division → { quotient, remainder } | | idivmod(v) | — | Integer division → { quotient, remainder } |

Raw operations (operate directly on scaled values, no configuration validation):

| Instance | Description (raw) | |------------|----------------------------| | plus(v) | Addition without scaling | | minus(v) | Subtraction without scaling| | times(v) | Multiplication without scaling | | ratio(v) | Division without scaling | | rem(v) | Remainder without scaling |

Comparison

Regular comparisons (validate configuration):

| Instance | Static | Returns | |-----------|--------------------------------|---------------| | cmp(v) | — | -1 \| 0 \| 1| | eq(v) | — | boolean | | gt(v) | — | boolean | | gte(v) | — | boolean | | lt(v) | — | boolean | | lte(v) | — | boolean |

Raw comparisons (compare scaled values directly, no validation — main build only):

cmpRaw(v), eqRaw(v), gtRaw(v), gteRaw(v), ltRaw(v), lteRaw(v).

Rounding & Scaling

| Method | Description | |-------------------------------------|-----------------------------------------------------| | round(dp?, rm?) | Round to dp decimal places | | prec(sd, rm?) | Round to sd significant digits | | ceil() | Round up to integer | | floor() | Round down to integer | | trunc() | Truncate toward zero | | scale(newScale, rm?) | Rescale to newScale decimal places | | shiftedBy(n) | Shift decimal point by n places | | clamp(min, max) | Clamp value between min and max (main only) | | toNearest(increment, rm?) | Round to nearest multiple of increment (main only)|

Formatting & Conversion

| Method | Description | |---------------------------------------|--------------------------------------------------| | toString() | Decimal string representation | | toNumber(places?) | Convert to number | | toFixed(places?, rm?) | Fixed‑point notation string | | toExponential(dp?, rm?) | Scientific notation string | | toPrecision(sd, rm?) | Format to significant digits | | toFormat(dp?, rm?) | String with thousands separators (minimal build) | | toJSON() | JSON serialization (same as toString()) | | valueOf() | Returns toString() | | toBinary(sd?, rm?) | Binary string (main only) | | toOctal(sd?, rm?) | Octal string (main only) | | toHex(sd?, rm?) / toHexadecimal() | Hex string (main only) |

Predicates & Inspection

| Method | Description | |---------------------------|----------------------------------------------| | isZero() | true if value is exactly zero | | isPositive() | true if value > 0 | | isNegative() | true if value < 0 | | isInteger() | true if value has no fractional part | | sign() | Returns -1, 0, 1, or NaN (main only) | | not() | Logical NOT — true if zero (main only) | | and(v), or(v), xor(v) | Logical AND / OR / XOR (main only) | | places() / decimalPlaces() | Returns context decimal places (main only) | | precision(z?) / sd(z?) | Returns significant digits (main only) | | raw() | Returns the internal bigint (main only) | | typeof() | Returns "FixedPrecision" (main only) |

Logarithms (main build only)

| Instance | Static | Description | |-------------|------------------------------|---------------------------| | ln() | FixedPrecision.ln(v) | Natural logarithm | | log(b?) | FixedPrecision.log(v, b?) | Logarithm (base optional) | | log2() | FixedPrecision.log2(v) | Base‑2 logarithm | | log10() | FixedPrecision.log10(v) | Base‑10 logarithm | | exp() | FixedPrecision.exp(v) | e raised to the value |

Trigonometry (main build only)

Standard: sin(), cos(), tan()
Reciprocal: sec(), csc(), cot()
Inverse: asin(), acos(), atan(), atan2(x)
Inverse reciprocal: acot(), asec(), acsc()
Hyperbolic: sinh(), cosh(), tanh()
Reciprocal hyperbolic: sech(), csch(), coth()
Inverse hyperbolic: asinh(), acosh(), atanh()
Inverse reciprocal hyperbolic: asech(), acsch(), acoth()

All are available as both instance (value.sin()) and static (FixedPrecision.sin(value)) methods.

Statistics

| Static method | Description | |---------------------------------------------|-----------------------------------| | FixedPrecision.min(...vals) | Minimum value (array or rest) | | FixedPrecision.max(...vals) | Maximum value (array or rest) | | FixedPrecision.sum(...vals) | Sum of values (array or rest) | | FixedPrecision.hypot(...vals) | Hypotenuse — sqrt(sum of squares) | | FixedPrecision.random(decimalPlaces?) | Random value 0–1 at given places |

Constants (main build only)

| Static method | Value | |--------------------------|------------------------------------| | FixedPrecision.PI() | π (pi) | | FixedPrecision.e() | Euler's number | | FixedPrecision.phi() | Golden ratio (1+√5)/2 | | FixedPrecision.sqrt2() | √2 |

Combinatorics (main build only)

FixedPrecision.factorial(n), FixedPrecision.permutations(n, k), FixedPrecision.combinations(n, k).

Fraction (main build only)

| Instance | Description | |-----------------|-------------------------------------------------| | .num() | Numerator of the reduced fraction | | .den() | Denominator of the reduced fraction | | .fraction(maxDen?) | Best rational approximation [num, den] |

Bitwise Operations (main build only)

bitAnd(v), bitOr(v), bitXor(v), bitNot(), leftShift(n), rightArithShift(n) — operate directly on the raw scaled bigint.

Vector Operations (main build only)

FixedPrecision.dot(a, b) → scalar dot product.
FixedPrecision.cross(a, b) → returns an array (cross product).

Method Chaining with Raw Values

All arithmetic and comparison methods accept FixedPrecisionValue (string | number | bigint | FixedPrecision), enabling concise chaining without explicit instantiation:

new FixedPrecision(100).add("50").sub(25n).mul(2).div("5");       // "50"
new FixedPrecision(10.5).add(5).div(3).gt(5);                     // true
new FixedPrecision("1.23").plus("2.00").times("3.00");           // raw chain

Type behavior:

  • string / number → decimal values, automatically scaled.
  • bigint → treated as already scaled (pre‑scaled). See below.
  • FixedPrecision → requires matching precision context (for scaled operations).

BigInt Warning

critical: bigint values are treated as pre‑scaled, not as decimal values.

new FixedPrecision("1.23");    // value = 123000000 (assuming 8 decimal places)
new FixedPrecision(1.23);      // value = 123000000
new FixedPrecision(123000000n); // value = 123000000 (pre‑scaled)
new FixedPrecision(123n);      // value = 123 (0.00000123 — NOT 123.00!)

When chaining:

const a = new FixedPrecision("1.23");

a.add(2);            // adds 2.00000000   (number → scaled)
a.add(2n);           // adds 0.00000002   (bigint → pre‑scaled!)
a.add("2.00");       // adds 2.00000000   (string → scaled)
a.add(200000000n);   // adds 2.00000000   (bigint → pre‑scaled correctly)

Use bigint only when you have pre‑calculated scaled values. For literal decimal values, use number or string.

Minimal Build

Import a smaller entry point when you only need core decimal operations:

import FixedPrecision, { fixedconfig } from "fixed-precision/minimal";

The minimal build includes: creation, arithmetic, comparison, rounding/scaling, sqrt, random/min/max/sum, predicates, and common formatting/conversion. It omits the larger extended APIs: trigonometry, logarithms, matrix/vector, bitwise, combinatorics, fractions, constants, logical operations, raw comparisons, and advanced inspection methods.

Contributing

  1. Fork the repository.
  2. Create a new branch: git checkout -b feature-name.
  3. Commit your changes: git commit -m 'Add some feature'.
  4. Push to the branch: git push origin feature-name.
  5. Open a pull request.

License

Distributed under the MIT License. See the LICENSE file for more details.