Skip to content

Instantly share code, notes, and snippets.

@cho45
Last active November 12, 2022 04:18
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save cho45/9968462 to your computer and use it in GitHub Desktop.
Save cho45/9968462 to your computer and use it in GitHub Desktop.
function formatN (n) {
const unitList = ['y', 'z', 'a', 'f', 'p', 'n', 'u', 'm', '', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'];
const zeroIndex = 8;
const nn = n.toExponential(2).split(/e/);
let u = Math.floor(+nn[1] / 3) + zeroIndex;
if (u > unitList.length - 1) {
u = unitList.length - 1;
} else
if (u < 0) {
u = 0;
}
return nn[0] * Math.pow(10, +nn[1] - (u - zeroIndex) * 3) + unitList[u];
}
const array = [1e30, 1e9, 1e8, 1e7, 1e6, 2345, 100, 10, 1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 256e-9, 2.55e-12, 1e-13, -1e3, 1e-30];
for (let i = 0, len = array.length; i < len; i++) {
const n = array[i];
const formatted = formatN(n);
console.log(n, formatted);
}
1e+30 1000000Y
1000000000 1G
100000000 100M
10000000 10M
1000000 1M
2345 2.35k
100 100
10 10
1 1
0.01 10m
0.001 1m
0.0001 100u
0.00001 10u
0.000001 1u
2.56e-7 256n
2.55e-12 2.55p
1e-13 100f
-1000 -1k
1e-30 0.000001y
@KMurphs
Copy link

KMurphs commented Oct 26, 2021

Based on your comment @dirkgroenen.
A python implementation:

import math
SI_PREFIXES_CENTER_INDEX = 8
si_prefixes = ('y', 'z', 'a', 'f', 'p', 'n', 'μ', 'm', '', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')


def to_si_notation(value: float, precision: int = 1):
    """Transforms a float number to a string (in SI Notation) using SI prefixes.
    ``e.g. 123456 => '123.46k'``

    Adapted from: https://gist.github.com/cho45/9968462 

    Args:
        value (float): The value to be converted
        precision (int, optional): The number of decimal places to display. Defaults to 1.

    Returns:
        str: String representing 'value' in SI Notation
    """

    value = float(value)
    if (value == 0): return str(value)

    exponent = math.floor(math.log10(abs(value)))
    exponent_of_1000 = (math.ceil if exponent < 0 else math.floor)(exponent / 3)
    if (exponent_of_1000 == 0): return "{0:.{1}f}".format(value, precision)
    
    mantissa = "{0:.{1}f}".format(float((value / math.pow(10, exponent_of_1000 * 3))), precision)
    si_prefix = si_prefixes[exponent_of_1000 + SI_PREFIXES_CENTER_INDEX]
    return f"{mantissa}{si_prefix}"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment