Skip to content

Instantly share code, notes, and snippets.

@princejwesley
Last active August 26, 2016 11:13
Show Gist options
  • Save princejwesley/157de08ac4bed1c278f82a7902a16101 to your computer and use it in GitHub Desktop.
Save princejwesley/157de08ac4bed1c278f82a7902a16101 to your computer and use it in GitHub Desktop.
Numbers Precision
/*
three sgnificant figures for large numbers expressed using power of ten suffixes "k", "M" and "B". Ex: 12.3k, 1.45m, 534k
For sub 1000 and > 0 numbers, use 4 significant figures - ex: 12.34, 1.234, 123.4
For numbers above 10B, use scientific notation of the form 1.23x10^11
For numbers < 0.001, use scientific notation of the form 1.23x10^-5
For numbers in range 0.001 < n < 1.0, use 3 decimal places - ex: 0.123
*/
const precision = (() => {
const B = 1e9, M = 1e6, K = 1e3;
const precisionTypes = [
{ limit: 1, range: K, suffix: '', sig: 4 },
{ limit: K, range: M, suffix: 'k', sig: 3 },
{ limit: M, range: B, suffix: 'm', sig: 3 },
{ limit: B, range: 1e10, suffix: 'b', sig: 3 },
];
const EXPONENT_PATTERN = /(?:\.0+)?e\+?/;
return (num) => {
let numeric, decimal, types = precisionTypes, r;
const sign = num < 0 ? '-' : '';
num = Math.abs(num);
if (!num || typeof num !== 'number') { return sign + num; }
// num < 0.001 or num > 10B
if (num > 1e10 || num < 1e-3) {
if (num | 0 === num && num > -1e3 && num < 0) {
return sign + num;
}
return sign + num.toExponential(2)
.replace(EXPONENT_PATTERN, '⨯10^');
}
// 0.001 < num < 1.0
if (num < 1) {
return sign + num.toFixed(3);
}
if ((num | 0) === num && num < 10 * K) {
return sign + num;
}
for (r = 0; r < types.length; r++) {
if (num < types[r].range) {
if (num >= K) {
num = num | 0;
num = num / types[r].limit;
}
numeric = num | 0;
decimal = num - numeric;
if (decimal) {
return sign + ((numeric + decimal).toFixed(types[r].sig - ("" + numeric).length))
+ types[r].suffix;
}
return sign + numeric + types[r].suffix;
}
}
}
})();
let data = [
-1, -0.00234533,
0, 10, 99, 999,
99.123, 9.12345, 199.2,
678.234, 123456789012,
1000, 1001, 99892,
12345678, 1234567890
];
data.forEach(function(d) {
console.log(d, precision(d))
})
@princejwesley
Copy link
Author

princejwesley commented Jul 18, 2016

~  node test.js
-1 '-1'
-0.00234533 '-2.35⨯10^-3'
0 '0'
10 '10'
99 '99'
999 '999'
99.123 '99.12'
9.12345 '9.123'
199.2 '199.2'
678.234 '678.2'
123456789012 '1.23⨯10^11'
1000 '1k'
1001 '1k'
99892 '99.9k'
12345678 '12.3m'
1234567890 '1.23b'

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