Skip to content

bradenmacdonald/quantity-math-js

Repository files navigation

Quantity Math for JavaScript/TypeScript

This is a library for dealing with numbers with units like "10 meters".

Based on PQM, with extensive changes.

MIT licensed.

Features

  • Zero dependencies.
  • Only 4.5 KiB minified and gzipped.
  • Basic math operations: multiply, add, subtract, etc.
  • Supports tolerance values like "2±0.2 cm", and carries them through mathematical operations.
  • "Remembers" the units you input and uses them by default for output.
  • Metric prefixes for all SI units (e.g. km, MHz, μN)
  • Binary prefixes for all information units (e.g. kib, kiB, MiB)
  • Custom dimensions ("2 foo" times "6 bar" = "12 foo⋅bar") can be defined on the fly
  • Temperature units: K (Kelvins), degC (Celcius measurement), deltaC (Celcius difference), degF (Fahrenheit measurement)
  • Supports "%" (percent) as a unit (50% of 50% is 25%, not "0.25 % %"; 50% of 400g is 200g, not "20000 g %")
  • Faster than any comparable libraries for its feature set (you can run the benchmark yourself with deno bench):
    • Quantity conversions:
      • 1.1x faster than PQM
      • 1.6x faster than mathjs
      • 2.1x faster than unitmath
      • 3.0x faster than js-quantities
    • Custom dimensions
      • 1.2x faster than mathjs
      • 1.9x faster than unitmath
      • PQM and js-quantities don't support custom dimensions

Missing Features

  • Some mathematical operations (e.g. division, sqrt) are not implemented yet because I didn't need them yet - feel free to add them.
  • Some units are not supported because I didn't need them yet - feel free to add them (e.g. radiation, luminosity, tsp, oz).
  • Array/vector operations (do math with many similar unit values efficiently) are not supported.
  • Handling of "significant figures" is only partially implemented and needs improvement.
  • This library generally tries not to support units that can be considered deprecated (like "bar", "dram", "furlong", "league", "poise", etc.) or that are ambiguous (like "ton", "gallon", etc.).

Installation

  • Deno: deno add @bradenmacdonald/quantity-math-js
  • Deno (no install): import { Quantity } from "jsr:@bradenmacdonald/quantity-math-js@1.2.1";
  • NPM: npx jsr add @bradenmacdonald/quantity-math-js
  • Yarn: yarn dlx jsr add @bradenmacdonald/quantity-math-js
  • pnpm: pnpm dlx jsr add @bradenmacdonald/quantity-math-js
  • Bun: bunx jsr add @bradenmacdonald/quantity-math-js
  • Browser:
    <script type="module">
      import { Quantity } from "https://esm.sh/jsr/@bradenmacdonald/quantity-math-js@1.2.1";
      // Or:
      const { Quantity } = await import('https://esm.sh/jsr/@bradenmacdonald/quantity-math-js@1.2.1');
    </script>

Basic Usage

Importing:

import { Q, Quantity } from "@bradenmacdonald/quantity-math-js";

Constructing a quantity value:

new Quantity(10, { units: "cm" });
// or
Q`10 cm`;
// or
Q("10 cm");

Adding two quantities:

const x = Q`5 m`;
const y = Q`20 cm`;
const z = x.add(y);
z.toString(); // "5.2 m"

Multiplying two quantities:

const x = Q`5 kg`;
const y = Q`2 m`;
const z = x.multiply(y);
z.toString(); // "10 kg⋅m"

Serialize to simple object, using same units:

const x = new Quantity(5, { units: "lb" });
x.get(); // { magnitude: 5, units: "lb" }

Convert a quantity to the specified units:

const x = Q`10 cm`;
x.convert("in").get(); // { magnitude: 3.9370078740157486, units: "in" }
x.convert("mm").toString(); // "100 mm"

Simplify units:

const x = new Quantity(5, { units: "kg^2⋅m^2⋅s^-4⋅A^-2" });
x.toSI().toString(); // "5 kg/F"

Error/uncertainty/tolerance

You can specify a "plus/minus" value (in the same units). Operations like addition and multiplication will preserve the plus/minus value, following the standard rules (i.e. addition adds the absolute uncertainty, multiplication adds the relative uncertainty, etc.).

const x = new Quantity(4.52, { units: "cm", plusMinus: 0.02 }); // 4.52±0.02 cm
const y = Q`2±0.2 cm`; // Or use the Q string syntax
const z = x.multiply(y); // z = xy = 9.04 ± 0.944 cm²
z.get(); // { magnitude: 9.04, units: "cm^2", plusMinus: 0.944 }
z.toString(); // "9.0±0.9 cm^2" (toString() will automatically round the output)

Custom units

Any unit name that starts with an underscore is considered to be a base custom unit (prefixed custom units are not supported). So you can define and use arbitrary units on the fly:

const f = new Quantity(10, { units: "_foo" });
const b = new Quantity(2, { units: "_bar" });
const fb = f.multiply(b);
fb.toString(); // "20 _foo⋅_bar"
fb.multiply(f).toString(); // "200 _foo^2⋅_bar"

Running tests

To run the tests, code formatter, linter, etc. you need to use Deno. The commands are standard:

deno lint
deno fmt
deno test

About

A library for dealing with numbers with units like "10 meters"

Resources

License

Stars

Watchers

Forks

Packages

No packages published