Skip to content

Unit System

a-calc provides a complete unit system including:

  • Unit arithmetic: calculations with units attached to numbers
  • Unit conversion: converting between units (cents→dollars, meters→kilometers, etc.)
  • Unit position formatting: controlling where units appear in output

Unit Arithmetic

Enabling Unit Mode

Use _unit: true to enable unit arithmetic:

javascript
import { calc } from "a-calc";

calc("100$ + 50$", { _unit: true }); // '150$'
calc("10kg + 5kg", { _unit: true }); // '15kg'
calc("50% + 30%", { _unit: true }); // '80%'

Unit Extraction Rules

a-calc automatically extracts units from the end of numbers:

javascript
calc("100$", { _unit: true }); // '100$'
calc("15%", { _unit: true }); // '15%'
calc("3.14π", { _unit: true }); // '3.14π'

Note

Units must be immediately after the number with no space:

javascript
calc("100$", { _unit: true }); // ✓ correct
calc("100 $", { _unit: true }); // ✗ wrong — unit will be ignored

Complex Expressions

Unit arithmetic supports complex math expressions:

javascript
calc("(100$ + 50$) * 2", { _unit: true }); // '300$'
calc("100$ * 3 - 50$", { _unit: true }); // '250$'
calc("1000$ / 4", { _unit: true }); // '250$'

Units in Variables

Variable values can also contain units:

javascript
calc("price + discount", {
  price: "100$",
  discount: "20$",
  _unit: true,
}); // '120$'

Removing Units

Use !u or !uh (without arguments) to strip units from the result:

javascript
calc("100$ + 50$", { _unit: true }); // '150$'
calc("100$ + 50$| !u", { _unit: true }); // '150'

Combining Units with Formatting

javascript
calc("100.5$ + 50.3$ | =2", { _unit: true }); // '150.80$'
calc("1000$ + 500$ | ,", { _unit: true }); // '1,500$'
calc("10000$ * 1.5 | =2,", { _unit: true }); // '15,000.00$'

Unit Position Formatting

Control where the unit symbol appears in the output.

Syntax Overview

SyntaxDescriptionExample
!u:unitShow unit (position configurable)100100$
!ua:unitUnit after number100100$
!ub:unitUnit before number100$100
!um:unitUnit in middle-100-$100
!uh:unitConvert only, hide unit100¢1

The simplest syntax. Unit appears after the number by default:

javascript
calc("100 | !u:$"); // '100$'
calc("100.5 | =2 !u:$"); // '100.50$'

Set a global default position with set_config:

javascript
import { calc, set_config } from "a-calc";

set_config({ _unit_default_position: "before" });
calc("100 | !u:$"); // '$100'

set_config({ _unit_default_position: "middle" });
calc("-100 | + !u:$"); // '-$100'

!ua:unit — Unit After Number

javascript
calc("100 | !ua:$"); // '100$'
calc("-50 | + !ua:$"); // '-50$'
calc("1234.5 | =2, !ua:$"); // '1,234.50$'

!ub:unit — Unit Before Number

javascript
calc("100 | !ub:$"); // '$100'
calc("-50 | !ub:$"); // '$-50'
calc("1234.5 | =2, !ub:$"); // '$1,234.50'

!um:unit — Unit in Middle

Places the currency symbol between the sign and the number — common in financial displays:

javascript
calc("8 | + !um:$"); // '+$8'
calc("-6 | + !um:$"); // '-$6'
calc("-12345.67 | +=2, !um:$"); // '-$12,345.67'

Middle Position

When there's no sign, !um behaves like !ub:

javascript
calc("100 | !um:$"); // '$100' (no sign, same as !ub)
calc("100 | + !um:$"); // '+$100' (with sign, in middle)

!uh:unit — Convert Without Showing Unit

Converts the value but doesn't display the unit:

javascript
calc("100 | =2 !uh:$", {
  _unit_convert_out: { $: { "¢": 0.01 } },
}); // '1.00' (100¢ → 1$, unit hidden)

Unit Conversion

Configuration

Keyed by output unit:

javascript
calc("100 | =2 !ua:$", {
  _unit_convert_out: {
    $: { "¢": 0.01 }, // ¢ × 0.01 = $
  },
}); // '1.00$' (100¢ → 1$)

_unit_convert_in

Keyed by input unit (automatically converted to _unit_convert_out format):

javascript
calc("100 | =2 !ua:$", {
  _unit_convert_in: {
    "¢": { $: 0.01 },
  },
}); // '1.00$'

Conversion Rule Formats

javascript
_unit_convert_out: {
  '$': {
    '¢': 0.01,                          // number: multiply by this
    'mill': { mul: 0.001 },             // object mul
    'large': { div: 100 },              // object div
    'custom': (v, inUnit, outUnit) => v / 7.2,  // function
    'fn': { fn: (v) => v / 7.2 }       // object fn
  }
}

Pure Config Mode

Control conversion entirely through config options:

javascript
calc("100 | =2", {
  _unit_convert_out: { $: { "¢": 0.01 } },
  _unit_default_out: "$",
  _unit_default_in: "¢",
  _unit_default_position: "before",
}); // '$1.00'

Unit Position Mapping

Pre-configure positions for different units:

javascript
calc("100 | !u:$", {
  _unit_position_map: {
    $: "before",
    "€": "middle",
    "¥": "after",
  },
}); // '$100'

Config Reference

OptionTypeDescription
_unitbooleanEnable unit arithmetic mode
_unit_convert_outobjectConversion map (output unit as key)
_unit_convert_inobjectConversion map (input unit as key)
_unit_default_outstring | string[]Default output unit
_unit_default_instring | string[]Default input unit
_unit_default_position'after' | 'before' | 'middle'Global unit position
_unit_position_mapobjectUnit-to-position mapping
_unit_thousands_mapobjectUnit-to-thousands-preset mapping

Released under the MIT License