# @thi.ng/units

0.4.46 • Public • Published

[!NOTE] This is one of 192 standalone projects, maintained as part of the @thi.ng/umbrella monorepo and anti-framework.

Extensible SI unit creation, conversions, quantities & calculations (incl. ~170 predefined units & constants).

All unit definitions, quantities & conversions are based on the SI unit system & concepts described here:

The overall conversion approach is inspired & partially based on:

### Unit definitions

Each unit is defined via a 7-dimensional vector representing individual exponents for each of the SI base unit dimensions, in order:

id SI dimension Base unit Base unit symbol
0 mass kilogram kg
1 length meter m
2 time second s
3 current ampere A
4 temperature kelvin K
5 amount of substance mole mol
6 luminous intensity candela cd

Dimensionless units (e.g. radian, byte) are supported too and represented by a vector with all dimensions set to zero.

Additionally, we also define a scale factor and zero offset for each unit, with most dimensions' base units usually using a factor of 1 and no offset.

For example, here's how we can define kilograms and meters:

```import { coherent, unit } from "@thi.ng/units";

// kilogram, SI dimension 0
const KG = coherent(0);
// { dim: [ 1, 0, 0, 0, 0, 0, 0 ], scale: 1, offset: 0, coherent: true }

// meters, SI dimension 1
const M = coherent(1);
// { dim: [ 0, 1, 0, 0, 0, 0, 0 ], scale: 1, offset: 0, coherent: true }

// kelvin, SI dimension 4 (here without syntax sugar)
const K = unit(4, 1, 0, true);
// { dim: [ 0, 0, 0, 0, 1, 0, 0 ], scale: 1, offset: 0, coherent: true }

// fahrenheit, SI dim 4 with custom scale factor and zero offset
const F = unit(4, 1 / 1.8, 459.67 / 1.8);
// { dim: [ 0, 0, 0, 0, 1, 0, 0 ],  scale: 0.5555, offset: 255.3722, coherent: false }```

More complex units like electrical resistance (e.g. ohm) are based on more than a single dimension:

```import { div, A, V } from "@thi.ng/units";

// ohm = volt / ampere
div(V, A)
// { dim: [ 1, 2, -3, -2, 0, 0,  0 ], scale: 1, offset: 0, coherent: true }```

This dimension vector represents the unit definition for (see SI derived units):

Ω = kg⋅m2⋅s−3⋅A−2

Btw. The `formatSI()` function can be used to format a unit's dimension vector:

```import { div, formatSI, A, V } from "@thi.ng/units";

formatSI(div(V, A));
// "kg·m2·s-3·A-2"```

### Predefined units

The following units are provided as "builtins", here grouped by dimension:

#### Acceleration

Unit name Variable name Description
`m/s2` `m_s2` meter per second squared
`ft/s2` `ft_s2` foot per second squared
`rad/s2` `rad_s2` radian per second squared
`g0` `g0` standard gravity

#### Angle

Unit name Variable name Description
`arcmin` `arcmin` arc minute
`arcsec` `arcsec` arc second
`deg` `deg` degree
`gon` `gon` gradian
`rad` `rad` radian
`sr` `sr` steradian
`turn` `turn` turn

#### Area

Unit name Variable name Description
`m2` `m2` square meter
`cm2` `cm2` square centimeter
`mm2` `mm2` square millimeter
`km2` `km2` square kilometer
`ha` `ha` hectar
`ac` `ac` acre
`sqin` `sqin` square inch
`sqft` `sqft` square foot
`sqmi` `sqmi` square mile

#### Data

Unit name Variable name Description
`bit` `bit` bit
`kbit` `kbit` kilobit
`Mbit` `Mbit` megabit
`Gbit` `Gbit` gigabit
`Tbit` `Tbit` terabit
`kibit` `kibit` kibibit (1024)
`Mibit` `Mibit` mebibit (1024)
`Gibit` `Gibit` gibibit (1024)
`Tibit` `Tibit` tebibit (1024)
`B` `B` byte (8 bit)
`kB` `kB` kilobyte (metric)
`MB` `MB` megabyte (metric)
`GB` `GB` gigabyte (metric)
`TB` `TB` terabyte (metric)
`PB` `PB` petabyte (metric)
`EB` `EB` exabyte (metric)
`KiB` `KiB` kibibyte (1024)
`MiB` `MiB` mebibyte (1024)
`GiB` `GiB` gibibyte (1024)
`TiB` `TiB` tebibyte (1024)
`PiB` `PiB` pebibyte (1024)
`EiB` `EiB` exbibyte (1024)

#### Density

Unit Variable name Description
`kg/m3` `kg_m3` density
`1/inch` `dpi` dots per inch

#### Electric current

Unit Variable name Description
`A` `A` ampere
`mA` `mA` milliampere
`mAh` `mAh` milliampere-hours
`C` `C` coulomb
`V` `V` volt
`mV` `mV` millivolt
`kV` `kV` kilovolt
`MV` `MV` megavolt
`F` `F` farad
`pF` `pF` picofarad
`µF` `µF` microfarad
`Ω` `Ω` / `ohm` ohm
`kΩ` `kΩ` / `kohm` kiloohm
`MΩ` `MΩ` / `Mohm` megaohm
`GΩ` `GΩ` / `Gohm` gigaohm
`S` `S` siemens
`Wb` `Wb` weber
`T` `T` tesla
`H` `H` henry

#### Energy

Unit Variable name Description
`J` `J` joule
`kJ` `kJ` kilojoule
`MJ` `MJ` megajoule
`GJ` `GJ` gigajoule
`cal` `cal` calorie
`kcal` `kcal` kilocalorie

#### Force

Unit Variable name Description
`N` `N` newton

#### Frequency

Unit Variable name Description
`Hz` `Hz` hertz
`kHz` `KHz` kilohertz
`MHz` `MHz` megahertz
`GHz` `GHz` gigahertz
`THz` `THz` terahertz
`rpm` `rpm` rotation per minute
`ω` `ω` / `omega` radian per second

#### Length

Unit name Variable name Description
`m` `m` meter
`Å` `angstrom` angstrom
`nm` `nm` nanometer
`µm` `µm` micrometer
`mm` `mm` millimeter
`cm` `cm` centimeter
`km` `km` kilometer
`au` `au` astronomical unit
`pc` `pc` parsec
`ly` `ly` light year
`in` `in` inch
`mil` `mil` / `thou` 1/1000th inch
`ft` `ft` foot
`yd` `yd` yard
`mi` `mi` mile
`nmi` `nmi` nautical mile
`pica` `pica` pica
`point` `point` point

#### Luminous intensity

Unit Variable name Description
`cd` `cd` candela
`lm` `lm` lumen
`lx` `lx` lux

#### Mass

Unit name Variable name Description
`µg` `µg` microgram
`mg` `mg` milligram
`g` `g` gram
`kg` `kg` kilogram
`t` `t` tonne
`kt` `kt` kilotonne
`Mt` `Mt` megatonne
`Gt` `Gt` gigatonne
`lb` `lb` imperial pound
`st` `st` stone

#### Parts per notation

https://en.wikipedia.org/wiki/Parts-per_notation

Unit name Variable name Description
`%` `percent` part per hundred
`‰` `permille` part per thousand
`‱` `permyriad` part per ten thousand
`pcm` `pcm` part per hundred thousand
`ppm` `ppm` part per million
`ppb` `ppb` part per billion
`ppt` `ppt` part per trillion

#### Power

Unit name Variable name Description
`W` `W` watt
`mW` `mW` milliwatt
`kW` `kW` kilowatt
`MW` `MW` megawatt
`GW` `GW` gigawatt
`TW` `TW` terawatt
`Wh` `Wh` watt-hour
`kWh` `kWh` kilowatt-hour

#### Pressure

Unit name Variable name Description
`Pa` `Pa` pascal
`kPa` `KPa` kilopascal
`MPa` `MPa` megapascal
`GPa` `GPa` gigapascal
`at` `at` technical atmosphere
`atm` `atm` atmosphere
`bar` `bar` bar
`psi` `psi` pound per square inch

#### Speed

Unit Variable name Description
`m/s` `m_s` meter per second
`km/h` `km_h` kilometer per hour
`mph` `mph` mile per hour
`kn` `kn` knot

#### Substance

Unit Variable name Description
`mol` `mol` mole

#### Temperature

Unit Variable name Description
`K` `K` kelvin
`℃` `celsius` degree celsius
`℉` `fahrenheit` degree fahrenheit

#### Time

Unit Variable name Description
`s` `s` second
`ms` `ms` millisecond
`µs` `µs` microsecond
`ns` `ns` nanosecond
`min` `min` minute
`h` `h` hour
`d` `d` day
`week` `week` week
`month` `month` month (30 days)
`year` `year` year (365.25 days)

#### Volume

Unit Variable name Description
`m3` `m3` cubic meter
`mm3` `mm3` cubic millimeter
`cm3` `cm3` cubic centimeter
`km3` `km3` cubic kilometer
`l` `l` liter
`cl` `cl` centiliter
`ml` `ml` milliliter
`gal` `gal` imperial gallon
`pt` `pt` imperial pint
`fl oz` `floz` imperial fluid ounce
`us gal` `us_gal` US gallon
`us pt` `us_pt` US pint
`us cup` `us_cup` US cup
`us fl oz` `us_floz` US fluid ounce

### Creating & deriving units

#### Using standard metric prefixes

Existing coherent units can be prefixed to produce derived versions:

```import { prefix, Hz } from "@thi.ng/units";

// define micrometer (also available as preset)
prefix("µ", "m")
// { dim: [ 0, 1, 0, 0, 0, 0, 0 ], scale: 0.000001, offset: 0, coherent: false }

// define kKhz
prefix("k", Hz);
// { dim: [ 0, 0, -1, 0, 0, 0, 0 ], scale: 1000, offset: 0, coherent: false }```

#### Unit combinators

The following combinators can be used to derive scaled and/or more complex units (or quantities) in multiple SI dimensions:

```import { div, mul, pow, prefix, reciprocal, bit, m, s } from "@thi.ng/units";

// acceleration (meter per second squared)
const m_s2 = div(m, pow(s, 2));
// { dim: [ 0, 1, -2, 0, 0, 0,  0 ], scale: 1, offset: 0, coherent: false }

// define kilowatt-hour (also available as preset)
const kWh = mul(prefix("k","W"), "h");
// { dim: [ 1, 2, -2, 0, 0, 0, 0 ], scale: 3600000, offset: 0, coherent: false }

// define `word` as 16 bits
const word = mul(bit, 16);
// { dim: [ 0, 0, 0, 0, 0, 0, 0 ], scale: 16, offset: 0, coherent: false }

// Hz = 1/s
const Hz = reciprocal(s);
// { dim: [ 0, 0, -1, 0, 0, 0, 0 ], scale: 1, offset: 0, coherent: false }```

### Unit conversions

Units (and quantities) can be converted using `convert()`. Only units with compatible (incl. reciprocal) dimensions can be converted, otherwise an error will be thrown. On the other hand, all dimensionless units can be converted to other dimensionless units (even if it would be semantic nonsense).

Units can be specified in various ways:

```import { convert, div, reciprocal, h, km_h, mph, yd } from "@thi.ng/units";

// convert from km/h to mph using unit names
convert(100, "km/h", "mph");
// 62.13711922373341

// or using predefined unit constants directly
convert(60, mph, km_h);
// 96.56063999999998

// or using anonymous units (meter/second ⇒ yard/hour)
convert(1, "m/s", div(yd, h));
// 3937.007874015749

// convert into opposite direction (meter/second  ⇒ second/meter)
convert(10, "m/s", reciprocal("m/s"));
// 0.1```

Another example using dimensionless units (here angles, arc second ⇒ radian) to compute the distance of 10 arcsec on the earth surface (in meters):

```import { convert, R } from "@thi.ng/units";

// (also available as quantity EARTH_RADIUS, see section below)
const R = 6371000;

// 308.87479623488537```

### Quantities

The library also supports defining quantities, i.e. certain finite amounts of a given unit. These can be a number or vector-based and can be used for calculations & conversions using the above mentioned polymorphic functions: `div()`, `mul()`, `reciprocal()` and `convert()`.

Quantities are created via `quantity()` which acts as factory function for a thin `Quantity` class wrapper. The latter also implements the standard `IDeref` interface to obtain the unwrapped amount (though it only should be used for dimensionless quantities). Use `convert()` otherwise!

```import { convert, div, quantity } from "@thi.ng/units";

// (also available as preset)
const speedOfLight = quantity(299792458, "m/s");

// compute wavelength of a WiFi signal in millimeters
convert(div(speedOfLight, quantity(2.4,"GHz")), "mm");
// 124.9135```

Some examples using vector quantities:

```import { convert, mul, quantity, NONE } from "@thi.ng/units";

// DIN A4 paper size (also available as preset)
const A4 = quantity([210, 297], "mm");

// convert paper size to inches
convert(A4, "in");
// [ 8.2677, 11.6929 ]

// or calculate pixel dimensions @ 300 dpi
// the result of this product is dimensionless,
// so we use the NONE preset as target unit...
convert(mul(A4, quantity(300, "dpi")), NONE)
// [ 2480.314960629921, 3507.8740157480315 ]

// alternatively, dimensionless units can be deref'd directly
mul(A4, quantity(300, "dpi")).deref()
// [ 2480.314960629921, 3507.8740157480315 ]```

When combining different quantities, their units do not need to be the same:

```import { convert, mul, quantity } from "@thi.ng/units";

// compute 10 mm x 2 inch and convert to square centimeter
convert(mul(quantity(10, "mm"), quantity(2, "in")), "cm2")
// 5.08```

#### Constants

The following constants are provided (more to come):

Var name Unit Comment
`DIN_A0` ... `DIN_A8` 2d vector of `mm` Paper sizes(1)
`EARTH_GRAVITY` `m/s`
`EARTH_CIRCUMFERENCE` `m`
`EARTH_MASS` `kg`
`EARTH_RADIUS` `m`
`GRAVITATION` `kg-1·m3·s-2` Gravitational constant
`SPEED_OF_LIGHT` `m/s`
`SPEED_OF_SOUND_IN_AIR` `m/s` at 20 ℃
`SPEED_OF_SOUND_IN_WATER` `m/s` at 20 ℃
`US_ANSI_A` ... `US_ANSI_E` 2d vector of `inch` Paper sizes(1)
`US_ARCH_A` ... `US_ARCH_E` 2d vector of `inch` Paper sizes(1)
`US_LETTER` / `US_HALF_LETTER` 2d vector of `inch` Paper sizes(1)
`US_LEGAL` / `US_JUNIOR_LEGAL` 2d vector of `inch` Paper sizes(1)
• (1) - all paper sizes are also available as landscape presets (using `_LANDSCAPE` as suffix).

Densities of selected materials:

Var name Unit
`AIR` `kg/m3`
`ALUMINIUM` `kg/m3`
`CONCRETE` `kg/m3`
`COPPER` `kg/m3`
`DIAMOND` `kg/m3`
`GLASS` `kg/m3`
`GOLD` `kg/m3`
`ICE` `kg/m3`
`IRON` `kg/m3`
`NYLON` `kg/m3`
`PLASTIC` `kg/m3`
`PLATINUM` `kg/m3`
`SAND` `kg/m3`
`SALT_WATER` `kg/m3`
`SILICON` `kg/m3`
`SILVER` `kg/m3`
`STEEL` `kg/m3`
`TITANIUM` `kg/m3`
`WATER` `kg/m3`
`WOOD` `kg/m3`

## Status

BETA - possibly breaking changes forthcoming

Search or submit any issues for this package

## Installation

`yarn add @thi.ng/units`

ESM import:

`import * as units from "@thi.ng/units";`

Browser ESM import:

`<script type="module" src="https://esm.run/@thi.ng/units"></script>`

JSDelivr documentation

For Node.js REPL:

`const units = await import("@thi.ng/units");`

Package sizes (brotli'd, pre-treeshake): ESM: 4.77 KB

## API

Generated API docs

## Authors

If this project contributes to an academic publication, please cite it as:

```@misc{thing-units,
title = "@thi.ng/units",
author = "Karsten Schmidt",
note = "https://thi.ng/units",
year = 2021
}```

## Package Sidebar

### Install

`npm i @thi.ng/units`

### Repository

github.com/thi-ng/umbrella

40

0.4.46

Apache-2.0

94.6 kB

58