SiMin

2 min read Original article ↗

A lightweight format for writing numbers using scientific notation.

I wrote this to make it easy to allow applications to accept values with units gracefully. Although many languages implement scientific notation, I never found it as ergonomic as just using SI prefixes. Would you rather a user input a unitless 1.024e+6 or 1_000KiB?

How does it work?

A SiMin number has three parts: a value, prefix, and unit. Let's look at an example:

tokenize('-120mT') === [ '-120', 'm', 'T' ]
  • '120' is the value. It can optionally start with a + or -, and consists of digits, decimals, and underscores. All of the following are valid values:
    • 9_800
    • +1.20030
    • -2300.123_456
  • 'm' is the prefix. It is the longest valid SI prefix that the parser can find directly after the value.
  • 'T' is the unit. It's just the rest of the string after the prefix.

More examples

// parsing numbers
console.log(parseUnit("10MB"));     // [ 10000000, 'B' ]
console.log(parseUnit("100mV"));    // [ 0.1, 'V' ]
console.log(parseUnit("-1.2uT"));   // [ -0.0000012, 'T' ]
console.log(parseUnit("123.45A"));  // [ 123.45, 'A' ]

// you can use underscores to make things more readable
console.log(parseUnit("100_000_000"));  // [ 100000000, '' ]

// automatic BigInt for really large prefixes.
console.log(parseUnit("10_000EiB"));    // [ 115292150460684697600000n, 'B' ]

// use parse to ignore the unit
console.log(parse("920d"));         // 92

// tokenizing numbers (if you want to parse it yourself)
console.log(tokenize("50Mibps"));   // [ '50', 'Mi', 'bps' ]

// you can also get the info of any SI prefix
console.log(prefixData("Mi"));      // [ 2, 20, [Function: parseFloat] ]

Prefixes

Important

SiMin numbers that use the prefixes marked with 🔢 will parse to BigNums

Prefix Base Exponent
E 🔢 10 18
P 🔢 10 15
T 10 12
G 10 9
M 10 6
k 10 3
h 10 2
da 10 1
d 10 -1
c 10 -2
m 10 -3
u, μ 10 -6
n 10 -9
p 10 -12
f 10 -15
a 10 -18
Prefix Base Exponent
Ei 🔢 2 60
Pi 🔢 2 50
Ti 2 40
Gi 2 30
Mi 2 20
Ki 2 10