# units.convert
Converts a quantity between two units of the same dimension: length, mass,
area, volume, temperature or energy. `convertUnits("1", "in", "mm", 6)` is
`"25.4"`.
## Why decimal text and fractions
Every unit in `data/units.json` is defined by an exact fraction of the base
unit (metre, kilogram, square metre, cubic metre, kelvin, joule), and the value
arrives as decimal text, so the whole conversion is exact rational arithmetic.
The one rounding step is at the end, half away from zero, to `decimals`
places. The answer is therefore the same in TypeScript, Python and Rust, and it
is the answer you would get by hand. Multiplying floats is not: 0.75 in is
19.05 mm exactly, but `0.75 * 25.4` is 19.049999999999997, which rounds to
19.0 instead of 19.1.
The result has trailing zeros trimmed (`"25.4"`, not `"25.400000"`), and a
negative value that rounds to zero is `"0"`, never `"-0"`.
## Temperatures are affine
A temperature unit is `K = value x factor + offset`: degC has offset 273.15,
degF has factor 5/9 and offset 459.67 x 5/9, degR has factor 5/9. This
converts absolute temperatures (a reading on a thermometer). A temperature
difference (a rise of 10 degC is a rise of 18 degF) has no offset, so do not
convert differences with this function.
## Units
Symbols are case-sensitive and exact. Ambiguous names are deliberately not
symbols: there is `gal_us` and `gal_imp`, `ton_us` (short, 2000 lb) and
`ton_imp` (long, 2240 lb), but no `gal`, `pt` or `ton`. Use
`units.parse-quantity` to accept friendly spellings such as "lbs" or "feet".
- length: mm cm m km in ft yd mi nmi
- mass: mg g kg t gr oz lb st ton_us ton_imp
- area: mm2 cm2 m2 ha km2 in2 ft2 yd2 acre mi2
- volume: mL cm3 L m3 in3 ft3 floz_us cup_us pt_us qt_us gal_us floz_imp pt_imp qt_imp gal_imp
- temperature: K degC degF degR
- energy: J kJ MJ Wh kWh MWh cal kcal Btu
## Limits
`value` is `-?digits(.digits)?`: no thousands separators, no exponent, no
leading `+`. It may have at most 15 significant digits and 15 decimal places
(trailing zeros do not count). `decimals` is 0 to 12.
Those limits are what keep the Rust port exact in `i128`. The largest reduced
factor between any two units in the table is 1.8e17 (MWh to Btu), so the
numerator of the exact result is below 1e15 x 1.8e17 = 1.8e32 and the
denominator is below 1e15 x 1.8e17 too. The rounding step is long division one
digit at a time, which never holds more than ten times the denominator
(1.8e33), well inside `i128` (1.7e38). Adding a unit with a bigger factor
would need that bound checked again; the Rust arithmetic is checked and panics
rather than wrapping.
## Sources
- NIST Special Publication 811 (2008 edition), *Guide for the Use of the
International System of Units*, Appendix B.8 and B.9, conversion factors:
https://www.nist.gov/pml/special-publication-811 . Exact (boldface) there:
inch 0.0254 m, foot 0.3048 m, yard 0.9144 m, mile 1609.344 m, nautical mile
1852 m, grain 64.79891 mg, imperial gallon 4.54609 L, square foot
0.09290304 m2, thermochemical calorie 4.184 J, kilowatt hour 3.6 MJ, and the
temperature relations T/K = t/degC + 273.15, t/degC = (t/degF - 32)/1.8,
T/K = (T/degR)/1.8.
- International Yard and Pound Agreement, 1959 (published in the US Federal
Register as "Refinement of values for the yard and the pound"): 1 yd = 0.9144 m
and 1 lb = 0.45359237 kg exactly. The pound also follows from SP 811's exact
grain: 7000 gr x 64.79891 mg = 453.59237 g.
- NIST, "U.S. Survey Foot: Revised Unit Conversion Factors"
(https://www.nist.gov/pml/us-surveyfoot/revised-unit-conversion-factors):
the survey foot is retired from 2023-01-01, and the acre is 43560
international square feet = 4046.8564224 m2. SP 811 (2008) still lists the
survey-foot acre, 4046.873 m2; this table uses the international one.
- The US gallon is 231 cubic inches (3.785411784 L); pints, quarts, cups and
fluid ounces are 1/8, 1/4, 1/16 and 1/128 of it. Imperial pints, quarts and
fluid ounces are 1/8, 1/4 and 1/160 of the imperial gallon.
- The International Table Btu is derived from the IT calorie (4.1868 J, exact
in SP 811): 1 Btu = 4186.8 J/(kg K) x 0.45359237 kg x 5/9 K = 1055.05585262 J.
- 1 L = 1 dm3 exactly (12th CGPM, 1964).