Skip to content

Instantly share code, notes, and snippets.

@ajmas
Last active December 3, 2015 21:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ajmas/4193ac6911f5445ced37 to your computer and use it in GitHub Desktop.
Save ajmas/4193ac6911f5445ced37 to your computer and use it in GitHub Desktop.
Javascript code to an SI 'order of magnitude' prefix to a displayed value. For example, given 1000 and 'Hz', you will get 1kHz. For decimal number less than 1, big.js is needed to avoid errors. Note, I looked at using a mathematical approach to get the index, but it worked out to be about the same speed, so I opted for readability
//ref: https://en.wikipedia.org/wiki/Metric_prefix
function valueToMagnitude(value, unit, fixedPlaces) {
var unitExponents = [
[0,''],
[3,'k'],
[6,'M'],
[9,'G'],
[12,'T'],
[15,'P'],
[18,'E'],
[21,'Y']
];
// Note, that we may need to use big.js for other high precision
// decimal values. At this point I haven't had a need, so wasn't
// fussed to fix this up. An exercise for the reader, or me if I
// make the time
if ((Math.abs(value) > 0 && Math.abs(value) < 1)) {
return valueToMagnitudeVerySmall(value, unit, fixedPlaces);
}
var sign = (value<0?-1:1);
value = Math.abs(value);
var i = 0; idx=0;
for (i=unitExponents.length-1; i >=0; i--) {
if (value >= Math.pow(10, unitExponents[i][0])) {
idx = i;
break;
}
}
value = (value / Math.pow(10, unitExponents[idx][0]));
if (fixedPlaces !== undefined) {
value = Math.tofixed(value,fixedPlaces);
}
value = value * sign;
return value + ' ' + unitExponents[idx][1] + unit;
}
// Requires use of big.js
function valueToMagnitudeVerySmall(value, unit, fixedPlaces) {
var unitExponents = [
[-12,'p'],
[-9,'n'],
[-6,'μ'],
[-3,'m'],
[0,''],
[3,'k'],
[6,'M'],
[9,'G'],
[12,'T'],
[15,'P'],
[18,'E'],
[21,'Y']
];
var valueBG = new Big(value);
var sign = (valueBG.lt(0)?-1:1);
valueBG = valueBG.abs(valueBG);
var i=0; idx=unitExponents.length-1; match = false;
for (i=0; i < unitExponents.length; i++) {
if (valueBG.lte(new Big(10).pow(unitExponents[i][0]))) {
idx = i;
break;
}
}
valueBG = valueBG.div(new Big(10).pow(unitExponents[idx][0]));
// This will break with values smaller than the units we support
if (fixedPlaces !== undefined) {
valueBG = value.tofixed(fixedPlaces);
}
valueBG = valueBG.times(sign);
return valueBG + ' ' + unitExponents[idx][1] + unit;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment