SI Prefixes in JavaScript

Most people are familiar with a few of the more common prefixes used before many units to denote a fraction or a multiple of the unit - kilograms, megabytes, centimetres etc.. As well as these there a number of less well known ones, going right up to yotta and right down to yocto.

A while ago I wrote a post on SI Prefixes in Python to list all the prefixes along with their corresponding powers and multipliers. When I started writing an equivalent in JavaScript I soon hit a brick wall when I realised that JavaScript's Number type couldn't provide the precision needed.

Searching around for a solution to the problem I discovered the excellent math.js library which, amongst many other things, provides us with a BigNumber type and I thoroughly recommend reading the documentation here. This post covers my simple little JavaScript project to list the numeric SI prefixes.

This project consists of a JavaScript file called siprefixes.js as well as an HTML page and a few ancilliary files. You can download them as a zip or clone/download from Github if you prefer. The zip and repo include the minimized version of math.js called (you guessed it!) math.min.js.

Source Code Links

ZIP File
GitHub

Let's look at the source code.

siprefixes.js

window.onload = function()
{
    SIprefixes();
}


function SIprefixes()
{
    const ten = math.bignumber(10);

    const base10 = [{"prefix": "yotta", "power": 24},
                    {"prefix": "zetta", "power": 21},
                    {"prefix": "exa", "power": 18},
                    {"prefix": "peta", "power": 15},
                    {"prefix": "tera", "power": 12},
                    {"prefix": "giga", "power": 9},
                    {"prefix": "mega", "power": 6},
                    {"prefix": "kilo", "power": 3},
                    {"prefix": "hecto", "power": 2},
                    {"prefix": "deca", "power": 1},
                    {"prefix": "(none)", "power": 0},
                    {"prefix": "deci", "power": -1},
                    {"prefix": "centi", "power": -2},
                    {"prefix": "milli", "power": -3},
                    {"prefix": "micro", "power": -6},
                    {"prefix": "nano", "power": -9},
                    {"prefix": "pico", "power": -12},
                    {"prefix": "femto", "power": -15},
                    {"prefix": "atto", "power": -18},
                    {"prefix": "zepto", "power": -21},
                    {"prefix": "yocto", "power": -24}];

    for(let p of base10)
    {
        writeToConsole(p.prefix.padEnd(7, " "));
        writeToConsole("10^" + p.power.toString().padEnd(4, " ") + "=");
        writeToConsole(math.format(math.pow(ten, p.power), {notation: 'fixed'}).padStart(27, " ") + "<br />");
    }
}

In window.onload we simply call SIprefixes() which firstly initializes a constant to a math.js BigNumber with value 10 which of course is the base of the decimal system.

Next we create an array of objects containing the SI prefixes and their corresponding powers. (If you have heard of more than half of them give yourself a pat on the back.)

Finally we iterate the array. The first line in the loop simply prints out the prefix name, padded to format the output neatly. The second line prints out the power or exponent, again padded to keep things lined up neatly.

The last line is where it all happens. It is somewhat convoluted so I'll break it down.

math.pow(ten, p.power)

This is straightforward, it mirrors JavaScript's own Math.pow but can handle BigNumber types.

math.format(math.pow(ten, p.power), {notation: 'fixed'})

Here we wrap the call to math.pow in a call to math.format which formats the number as a string in accordance with second argument, in this case 'fixed'. Without this very large or very small numbers would be displayed in scientific notation, for example yotta or 10^24 would be shown as 1e+24 which is perfectly correct of course but not what I wanted for this project.

math.format(math.pow(ten, p.power), {notation: 'fixed'}).padStart(27, " ")

Finally we add a call to padStart to right-align the numbers.

Now open siprefixes.htm in your browser. This is the output.

The powers of 10 exhibit a very satisfying symmetry as well as some staggering largeness and smallness at the extreme ends. If you were baffled by these extremes I hope the output helps you to get your head round them.

If you are new to math.js I hope you were impressed by the small corner of it used here. I have a few more projects lined up which use further aspects of the library.