Format a number as 2.5K if a thousand or more, otherwise 900
JavascriptJqueryFormattingNumbersJavascript Problem Overview
I need to show a currency value in the format of 1K
of equal to one thousand, or 1.1K
, 1.2K
, 1.9K
etc, if its not an even thousands, otherwise if under a thousand, display normal 500
, 100
, 250
etc, using JavaScript to format the number?
Javascript Solutions
Solution 1 - Javascript
A more generalized version:
function nFormatter(num, digits) {
const lookup = [
{ value: 1, symbol: "" },
{ value: 1e3, symbol: "k" },
{ value: 1e6, symbol: "M" },
{ value: 1e9, symbol: "G" },
{ value: 1e12, symbol: "T" },
{ value: 1e15, symbol: "P" },
{ value: 1e18, symbol: "E" }
];
const rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
var item = lookup.slice().reverse().find(function(item) {
return num >= item.value;
});
return item ? (num / item.value).toFixed(digits).replace(rx, "$1") + item.symbol : "0";
}
/*
* Tests
*/
const tests = [
{ num: 0, digits: 1 },
{ num: 12, digits: 1 },
{ num: 1234, digits: 1 },
{ num: 100000000, digits: 1 },
{ num: 299792458, digits: 1 },
{ num: 759878, digits: 1 },
{ num: 759878, digits: 0 },
{ num: 123, digits: 1 },
{ num: 123.456, digits: 1 },
{ num: 123.456, digits: 2 },
{ num: 123.456, digits: 4 }
];
tests.forEach(function(test) {
console.log("nFormatter(" + test.num + ", " + test.digits + ") = " + nFormatter(test.num, test.digits));
});
Solution 2 - Javascript
Sounds like this should work for you:
function kFormatter(num) {
return Math.abs(num) > 999 ? Math.sign(num)*((Math.abs(num)/1000).toFixed(1)) + 'k' : Math.sign(num)*Math.abs(num)
}
console.log(kFormatter(1200)); // 1.2k
console.log(kFormatter(-1200)); // -1.2k
console.log(kFormatter(900)); // 900
console.log(kFormatter(-900)); // -900
Solution 3 - Javascript
ES2020 adds support for this in Intl.NumberFormat
Using notation as follows:
let formatter = Intl.NumberFormat('en', { notation: 'compact' }); // example 1 let million = formatter.format(1e6); // example 2 let billion = formatter.format(1e9); // print console.log(million == '1M', billion == '1B');
Note as shown above, that the second example produces 1B
instead of 1G
.
NumberFormat
specs:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat
- https://tc39.es/ecma402#numberformat-objects
Note that at the moment not all browsers support ES2020, so you may need this Polyfill: https://formatjs.io/docs/polyfills/intl-numberformat
Solution 4 - Javascript
Here's a simple solution that avoids all the if
statements (with the power of Math
).
var SI_SYMBOL = ["", "k", "M", "G", "T", "P", "E"];
function abbreviateNumber(number){
// what tier? (determines SI symbol)
var tier = Math.log10(Math.abs(number)) / 3 | 0;
// if zero, we don't need a suffix
if(tier == 0) return number;
// get suffix and determine scale
var suffix = SI_SYMBOL[tier];
var scale = Math.pow(10, tier * 3);
// scale the number
var scaled = number / scale;
// format number and add suffix
return scaled.toFixed(1) + suffix;
}
Bonus Meme
Solution 5 - Javascript
Further improving Salman's Answer because it returns nFormatter(33000) as 33.0K
function nFormatter(num) {
if (num >= 1000000000) {
return (num / 1000000000).toFixed(1).replace(/\.0$/, '') + 'G';
}
if (num >= 1000000) {
return (num / 1000000).toFixed(1).replace(/\.0$/, '') + 'M';
}
if (num >= 1000) {
return (num / 1000).toFixed(1).replace(/\.0$/, '') + 'K';
}
return num;
}
now nFormatter(33000) = 33K
Solution 6 - Javascript
A straight-forward approach has the best readability, and uses the least memory. No need to over-engineer with the use of regex, map objects, Math objects, for-loops, etc.
Formatting Cash value with K
const formatCash = n => {
if (n < 1e3) return n;
if (n >= 1e3) return +(n / 1e3).toFixed(1) + "K";
};
console.log(formatCash(2500));
Formatting Cash value with K M B T
const formatCash = n => {
if (n < 1e3) return n;
if (n >= 1e3 && n < 1e6) return +(n / 1e3).toFixed(1) + "K";
if (n >= 1e6 && n < 1e9) return +(n / 1e6).toFixed(1) + "M";
if (n >= 1e9 && n < 1e12) return +(n / 1e9).toFixed(1) + "B";
if (n >= 1e12) return +(n / 1e12).toFixed(1) + "T";
};
console.log(formatCash(1235000));
Using negative numbers
let format;
const number = -1235000;
if (number < 0) {
format = '-' + formatCash(-1 * number);
} else {
format = formatCash(number);
}
Solution 7 - Javascript
/**
* Shorten number to thousands, millions, billions, etc.
* http://en.wikipedia.org/wiki/Metric_prefix
*
* @param {number} num Number to shorten.
* @param {number} [digits=0] The number of digits to appear after the decimal point.
* @returns {string|number}
*
* @example
* // returns '12.5k'
* shortenLargeNumber(12543, 1)
*
* @example
* // returns '-13k'
* shortenLargeNumber(-12567)
*
* @example
* // returns '51M'
* shortenLargeNumber(51000000)
*
* @example
* // returns 651
* shortenLargeNumber(651)
*
* @example
* // returns 0.12345
* shortenLargeNumber(0.12345)
*/
function shortenLargeNumber(num, digits) {
var units = ['k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'],
decimal;
for(var i=units.length-1; i>=0; i--) {
decimal = Math.pow(1000, i+1);
if(num <= -decimal || num >= decimal) {
return +(num / decimal).toFixed(digits) + units[i];
}
}
return num;
}
Thx @Cos for comment, I removed Math.round10 dependency.
Solution 8 - Javascript
Give Credit to Waylon Flinn if you like this
This was improved from his more elegant approach to handle negative numbers and ".0" case.
The fewer loops and "if" cases you have, the better IMO.
function abbreviateNumber(number) {
const SI_POSTFIXES = ["", "k", "M", "G", "T", "P", "E"];
const sign = number < 0 ? '-1' : '';
const absNumber = Math.abs(number);
const tier = Math.log10(absNumber) / 3 | 0;
// if zero, we don't need a prefix
if(tier == 0) return `${absNumber}`;
// get postfix and determine scale
const postfix = SI_POSTFIXES[tier];
const scale = Math.pow(10, tier * 3);
// scale the number
const scaled = absNumber / scale;
const floored = Math.floor(scaled * 10) / 10;
// format number and add postfix as suffix
let str = floored.toFixed(1);
// remove '.0' case
str = (/\.0$/.test(str)) ? str.substr(0, str.length - 2) : str;
return `${sign}${str}${postfix}`;
}
jsFiddle with test cases -> https://jsfiddle.net/qhbrz04o/9/
Solution 9 - Javascript
this is is quite elegant.
function formatToUnits(number, precision) {
const abbrev = ['', 'k', 'm', 'b', 't'];
const unrangifiedOrder = Math.floor(Math.log10(Math.abs(number)) / 3)
const order = Math.max(0, Math.min(unrangifiedOrder, abbrev.length -1 ))
const suffix = abbrev[order];
return (number / Math.pow(10, order * 3)).toFixed(precision) + suffix;
}
formatToUnits(12345, 2)
==> "12.35k"
formatToUnits(0, 3)
==> "0.000"
Solution 10 - Javascript
You can use the d3-format package modeled after Python Advanced String Formatting PEP3101 :
var f = require('d3-format')
console.log(f.format('.2s')(2500)) // displays "2.5k"
Solution 11 - Javascript
By eliminating the loop in @martin-sznapka solution, you will reduce the execution time by 40%.
function formatNum(num,digits) {
let units = ['k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'];
let floor = Math.floor(Math.abs(num).toString().length / 3);
let value=+(num / Math.pow(1000, floor))
return value.toFixed(value > 1?digits:2) + units[floor - 1];
}
Speed test (200000 random samples) for different solution from this thread
Execution time: formatNum 418 ms
Execution time: kFormatter 438 ms it just use "k" no "M".."T"
Execution time: beautify 593 ms doesnt support - negatives
Execution time: shortenLargeNumber 682 ms
Execution time: Intl.NumberFormat 13197ms
Solution 12 - Javascript
I think it can be one solution.
var unitlist = ["","K","M","G"];
function formatnumber(number){
let sign = Math.sign(number);
let unit = 0;
while(Math.abs(number) > 1000)
{
unit = unit + 1;
number = Math.floor(Math.abs(number) / 100)/10;
}
console.log(sign*number + unitlist[unit]);
}
formatnumber(999);
formatnumber(1234);
formatnumber(12345);
formatnumber(123456);
formatnumber(1234567);
formatnumber(12345678);
formatnumber(-999);
formatnumber(-1234);
formatnumber(-12345);
formatnumber(-123456);
formatnumber(-1234567);
formatnumber(-12345678);
Solution 13 - Javascript
Short and generic method
You can make the COUNT_FORMATS
config object as long or short as you want, depending on the range of values you testing.
// Configuration
const COUNT_FORMATS =
[
{ // 0 - 999
letter: '',
limit: 1e3
},
{ // 1,000 - 999,999
letter: 'K',
limit: 1e6
},
{ // 1,000,000 - 999,999,999
letter: 'M',
limit: 1e9
},
{ // 1,000,000,000 - 999,999,999,999
letter: 'B',
limit: 1e12
},
{ // 1,000,000,000,000 - 999,999,999,999,999
letter: 'T',
limit: 1e15
}
];
// Format Method:
function formatCount(value)
{
const format = COUNT_FORMATS.find(format => (value < format.limit));
value = (1000 * value / format.limit);
value = Math.round(value * 10) / 10; // keep one decimal number, only if needed
return (value + format.letter);
}
// Test:
const test = [274, 1683, 56512, 523491, 9523489, 5729532709, 9421032489032];
test.forEach(value => console.log(`${ value } >>> ${ formatCount(value) }`));
Solution 14 - Javascript
Further improving @Yash's answer with negative number support:
function nFormatter(num) {
isNegative = false
if (num < 0) {
isNegative = true
}
num = Math.abs(num)
if (num >= 1000000000) {
formattedNumber = (num / 1000000000).toFixed(1).replace(/\.0$/, '') + 'G';
} else if (num >= 1000000) {
formattedNumber = (num / 1000000).toFixed(1).replace(/\.0$/, '') + 'M';
} else if (num >= 1000) {
formattedNumber = (num / 1000).toFixed(1).replace(/\.0$/, '') + 'K';
} else {
formattedNumber = num;
}
if(isNegative) { formattedNumber = '-' + formattedNumber }
return formattedNumber;
}
nFormatter(-120000)
"-120K"
nFormatter(120000)
"120K"
Solution 15 - Javascript
The simplest and easiest way of doing this is
new Intl.NumberFormat('en-IN', {
notation: "compact",
compactDisplay: "short",
style: 'currency',
currency: 'INR'
}).format(1000).replace("T", "K")
This works for any number. Including L
Cr
etc.
NOTE: Not working in safari.
Solution 16 - Javascript
Not satisfied any of the posted solutions, so here's my version:
-
Supports positive and negative numbers
-
Supports negative exponents
-
Rounds up to next exponent if possible
-
Performs bounds checking (doesn't error out for very large/small numbers)
-
Strips off trailing zeros/spaces
-
Supports a precision parameter
function abbreviateNumber(number,digits=2) { var expK = Math.floor(Math.log10(Math.abs(number)) / 3); var scaled = number / Math.pow(1000, expK);
if(Math.abs(scaled.toFixed(digits))>=1000) { // Check for rounding to next exponent scaled /= 1000; expK += 1; }
var SI_SYMBOLS = "apμm kMGTPE"; var BASE0_OFFSET = SI_SYMBOLS.indexOf(' ');
if (expK + BASE0_OFFSET>=SI_SYMBOLS.length) { // Bound check expK = SI_SYMBOLS.length-1 - BASE0_OFFSET; scaled = number / Math.pow(1000, expK); } else if (expK + BASE0_OFFSET < 0) return 0; // Too small
return scaled.toFixed(digits).replace(/(.|(..*?))0+$/,'$2') + SI_SYMBOLS[expK+BASE0_OFFSET].trim(); }
//////////////////
const tests = [ [0.0000000000001,2], [0.00000000001,2], [0.000000001,2], [0.000001,2], [0.001,2], [0.0016,2], [-0.0016,2], [0.01,2], [1,2], [999.99,2], [999.99,1], [-999.99,1], [999999,2], [999999999999,2], [999999999999999999,2], [99999999999999999999,2], ];
for (var i = 0; i < tests.length; i++) { console.log(abbreviateNumber(tests[i][0], tests[i][1]) ); }
Solution 17 - Javascript
2020 edition of Waylon Flinn's solution.
const SI_SYMBOLS = ["", "k", "M", "G", "T", "P", "E"];
const abbreviateNumber = (number, minDigits, maxDigits) => {
if (number === 0) return number;
// determines SI symbol
const tier = Math.floor(Math.log10(Math.abs(number)) / 3);
// get suffix and determine scale
const suffix = SI_SYMBOLS[tier];
const scale = 10 ** (tier * 3);
// scale the number
const scaled = number / scale;
// format number and add suffix
return scaled.toLocaleString(undefined, {
minimumFractionDigits: minDigits,
maximumFractionDigits: maxDigits,
}) + suffix;
};
Tests and examples:
const abbreviateNumberFactory = (symbols) => (
(number, minDigits, maxDigits) => {
if (number === 0) return number;
// determines SI symbol
const tier = Math.floor(Math.log10(Math.abs(number)) / 3);
// get suffix and determine scale
const suffix = symbols[tier];
const scale = 10 ** (tier * 3);
// scale the number
const scaled = number / scale;
// format number and add suffix
return scaled.toLocaleString(undefined, {
minimumFractionDigits: minDigits,
maximumFractionDigits: maxDigits,
}) + suffix;
}
);
const SI_SYMBOLS = ["", "k", "M", "G", "T", "P", "E"];
const SHORT_SYMBOLS = ["", "K", "M", "B", "T", "Q"];
const LONG_SYMBOLS = ["", " thousand", " million", " billion", " trillion", " quadrillion"];
const abbreviateNumberSI = abbreviateNumberFactory(SI_SYMBOLS);
const abbreviateNumberShort = abbreviateNumberFactory(SHORT_SYMBOLS);
const abbreviateNumberLong = abbreviateNumberFactory(LONG_SYMBOLS);
const tests = [1e5, -9e7, [1009999.999, 2],
[245345235.34513, 1, 1],
[-72773144123, 3]
];
const functions = {
abbreviateNumberSI,
abbreviateNumberShort,
abbreviateNumberLong,
};
tests.forEach((test) => {
const testValue = Array.isArray(test) ? test : [test];
Object.entries(functions).forEach(([key, func]) => {
console.log(`${key}(${testValue.join(', ')}) = ${func(...testValue)}`);
});
});
Solution 18 - Javascript
This post is quite old but I somehow reached to this post searching for something. SO to add my input Numeral js is the one stop solution now a days. It gives a large number of methods to help formatting the numbers
Solution 19 - Javascript
Here is an option using for
:
function numberFormat(d) {
for (var e = 0; d >= 1000; e++) {
d /= 1000;
}
return d.toFixed(3) + ['', ' k', ' M', ' G'][e];
}
let s = numberFormat(9012345678);
console.log(s == '9.012 G');
Solution 20 - Javascript
Adding on the top answer, this will give 1k for 1000 instead of 1.0k
function kFormatter(num) {
return num > 999 ? num % 1000 === 0 ? (num/1000).toFixed(0) + 'k' : (num/1000).toFixed(1) + 'k' : num
}
Solution 21 - Javascript
- Support negative number
- Checking for
!isFinite
- Change
' K M G T P E Z Y'
to' K M'
if you want the max unit isM
- Option for base ( 1K = 1000 / 1K = 1024 )
Number.prototype.prefix = function (precision, base) {
var units = ' K M G T P E Z Y'.split(' ');
if (typeof precision === 'undefined') {
precision = 2;
}
if (typeof base === 'undefined') {
base = 1000;
}
if (this == 0 || !isFinite(this)) {
return this.toFixed(precision) + units[0];
}
var power = Math.floor(Math.log(Math.abs(this)) / Math.log(base));
// Make sure not larger than max prefix
power = Math.min(power, units.length - 1);
return (this / Math.pow(base, power)).toFixed(precision) + units[power];
};
console.log('0 = ' + (0).prefix()) // 0.00
console.log('10000 = ' + (10000).prefix()) // 10.00K
console.log('1234000 = ' + (1234000).prefix(1)) // 1.2M
console.log('-10000 = ' + (-10240).prefix(1, 1024)) // -10.0K
console.log('-Infinity = ' + (-Infinity).prefix()) // -Infinity
console.log('NaN = ' + (NaN).prefix()) // NaN
Solution 22 - Javascript
A modified version of Waylon Flinn's answer with support for negative exponents:
function metric(number) {
const SI_SYMBOL = [
["", "k", "M", "G", "T", "P", "E"], // +
["", "m", "μ", "n", "p", "f", "a"] // -
];
const tier = Math.floor(Math.log10(Math.abs(number)) / 3) | 0;
const n = tier < 0 ? 1 : 0;
const t = Math.abs(tier);
const scale = Math.pow(10, tier * 3);
return {
number: number,
symbol: SI_SYMBOL[n][t],
scale: scale,
scaled: number / scale
}
}
function metric_suffix(number, precision) {
const m = metric(number);
return (typeof precision === 'number' ? m.scaled.toFixed(precision) : m.scaled) + m.symbol;
}
for (var i = 1e-6, s = 1; i < 1e7; i *= 10, s *= -1) {
// toggles sign in each iteration
console.log(metric_suffix(s * (i + i / 5), 1));
}
console.log(metric(0));
Expected output:
1.2μ
-12.0μ
120.0μ
-1.2m
12.0m
-120.0m
1.2
-12.0
120.0
-1.2k
12.0k
-120.0k
1.2M
{ number: 0, symbol: '', scale: 1, scaled: 0 }
Solution 23 - Javascript
This function could transform huge numbers (both positive & negative) into a reader friendly format without losing its precision:
function abbrNum(n) {
if (!n || (n && typeof n !== 'number')) {
return '';
}
const ranges = [
{ divider: 1e12 , suffix: 't' },
{ divider: 1e9 , suffix: 'b' },
{ divider: 1e6 , suffix: 'm' },
{ divider: 1e3 , suffix: 'k' }
];
const range = ranges.find(r => Math.abs(n) >= r.divider);
if (range) {
return (n / range.divider).toString() + range.suffix;
}
return n.toString();
}
/* test cases */
let testAry = [99, 1200, -150000, 9000000];
let resultAry = testAry.map(abbrNum);
console.log("result array: " + resultAry);
Solution 24 - Javascript
Improving @tfmontague's answer further to format decimal places. 33.0k to 33k
largeNumberFormatter(value: number): any {
let result: any = value;
if (value >= 1e3 && value < 1e6) { result = (value / 1e3).toFixed(1).replace(/\.0$/, '') + 'K'; }
if (value >= 1e6 && value < 1e9) { result = (value / 1e6).toFixed(1).replace(/\.0$/, '') + 'M'; }
if (value >= 1e9) { result = (value / 1e9).toFixed(1).replace(/\.0$/, '') + 'T'; }
return result;
}
Solution 25 - Javascript
I came up with a very code golfed one, and it is very short!
var beautify=n=>((Math.log10(n)/3|0)==0)?n:Number((n/Math.pow(10,(Math.log10(n)/3|0)*3)).toFixed(1))+["","K","M","B","T",][Math.log10(n)/3|0];
console.log(beautify(1000))
console.log(beautify(10000000))
Solution 26 - Javascript
Further improving Salman's Answer because of the cases like nFormatter(999999,1) that returns 1000K.
function formatNumberWithMetricPrefix(num, digits = 1) {
const si = [
{value: 1e18, symbol: 'E'},
{value: 1e15, symbol: 'P'},
{value: 1e12, symbol: 'T'},
{value: 1e9, symbol: 'G'},
{value: 1e6, symbol: 'M'},
{value: 1e3, symbol: 'k'},
{value: 0, symbol: ''},
];
const rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
function divideNum(divider) {
return (num / (divider || 1)).toFixed(digits);
}
let i = si.findIndex(({value}) => num >= value);
if (+divideNum(si[i].value) >= 1e3 && si[i - 1]) {
i -= 1;
}
const {value, symbol} = si[i];
return divideNum(value).replace(rx, '$1') + symbol;
}
Solution 27 - Javascript
Supports up to Number.MAX_SAFE_INTEGER
and down to Number.MIN_SAFE_INTEGER
function abbreviateThousands(value) {
const num = Number(value)
const absNum = Math.abs(num)
const sign = Math.sign(num)
const numLength = Math.round(absNum).toString().length
const symbol = ['K', 'M', 'B', 'T', 'Q']
const symbolIndex = Math.floor((numLength - 1) / 3) - 1
const abbrv = symbol[symbolIndex] || symbol[symbol.length - 1]
let divisor = 0
if (numLength > 15) divisor = 1e15
else if (numLength > 12) divisor = 1e12
else if (numLength > 9) divisor = 1e9
else if (numLength > 6) divisor = 1e6
else if (numLength > 3) divisor = 1e3
else return num
return `${((sign * absNum) / divisor).toFixed(divisor && 1)}${abbrv}`
}
console.log(abbreviateThousands(234523452345)) // 234.5b (billion)
console.log(abbreviateThousands(Number.MIN_SAFE_INTEGER)) // -9.0q (quadrillion)
Solution 28 - Javascript
function transform(value,args) {
const suffixes = ['K', 'M', 'B', 'T', 'P', 'E'];
if (!value) {
return null;
}
if (Number.isNaN(value)) {
return null;
}
if (value < 1000) {
return value;
}
const exp = Math.floor(Math.log(value) / Math.log(1000));
const returnValue = (value / Math.pow(1000, exp)).toFixed(args) + suffixes[exp - 1];
return returnValue;
}
transform(9999,2)
// "10.00K"
Solution 29 - Javascript
/*including negative values*/
function nFormatter(num) {
let neg = false;
if(num < 0){
num = num * -1;
neg = true;
}
if (num >= 1000000000) {
if(neg){
return -1 * (num / 1000000000).toFixed(1).replace(/\.0$/, '') + 'G';
}
return (num / 1000000000).toFixed(1).replace(/\.0$/, '') + 'G';
}
if (num >= 1000000) {
if(neg){
return -1 * (num / 1000000).toFixed(1).replace(/\.0$/, '') + 'M';
}
return (num / 1000000).toFixed(1).replace(/\.0$/, '') + 'M';
}
if (num >= 1000) {
if(neg){
return -1 * (num / 1000).toFixed(1).replace(/\.0$/, '') + 'K';
}
return (num / 1000).toFixed(1).replace(/\.0$/, '') + 'K';
}
return num;
}
Solution 30 - Javascript
I am using this function. It works for both php
and javascript
.
/**
* @param $n
* @return string
* Use to convert large positive numbers in to short form like 1K+, 100K+, 199K+, 1M+, 10M+, 1B+ etc
*/
function num_format($n) {
$n_format = null;
$suffix = null;
if ($n > 0 && $n < 1000) {
$n_format = Math.floor($n);
$suffix = '';
}
else if ($n == 1000) {
$n_format = Math.floor($n / 1000); //For PHP only use floor function insted of Math.floor()
$suffix = 'K';
}
else if ($n > 1000 && $n < 1000000) {
$n_format = Math.floor($n / 1000);
$suffix = 'K+';
} else if ($n == 1000000) {
$n_format = Math.floor($n / 1000000);
$suffix = 'M';
} else if ($n > 1000000 && $n < 1000000000) {
$n_format = Math.floor($n / 1000000);
$suffix = 'M+';
} else if ($n == 1000000000) {
$n_format = Math.floor($n / 1000000000);
$suffix = 'B';
} else if ($n > 1000000000 && $n < 1000000000000) {
$n_format = Math.floor($n / 1000000000);
$suffix = 'B+';
} else if ($n == 1000000000000) {
$n_format = Math.floor($n / 1000000000000);
$suffix = 'T';
} else if ($n >= 1000000000000) {
$n_format = Math.floor($n / 1000000000000);
$suffix = 'T+';
}
/***** For PHP ******/
// return !empty($n_format . $suffix) ? $n_format . $suffix : 0;
/***** For Javascript ******/
return ($n_format + $suffix).length > 0 ? $n_format + $suffix : 0;
}
Solution 31 - Javascript
I decided to expand a lot on @Novellizator's answer here to meet my needs. I wanted a flexible function to handle most of my formatting needs without external libraries.
Features
- Option to use order suffixes (k, M, etc.)
- Option to specify a custom list of order suffixes to use
- Option to constrain the min and max order
- Control over the number of decimal places
- Automatic order-separating commas
- Optional percent or dollar formatting
- Control over what to return in the case of non-numeric input
- Works on negative and infinite numbers
Examples
let x = 1234567.8;
formatNumber(x); // '1,234,568'
formatNumber(x, {useOrderSuffix: true}); // '1M'
formatNumber(x, {useOrderSuffix: true, decimals: 3, maxOrder: 1}); // '1,234.568k'
formatNumber(x, {decimals: 2, style: '$'}); // '$1,234,567.80'
x = 10.615;
formatNumber(x, {style: '%'}); // '1,062%'
formatNumber(x, {useOrderSuffix: true, decimals: 1, style: '%'}); // '1.1k%'
formatNumber(x, {useOrderSuffix: true, decimals: 5, style: '%', minOrder: 2}); // '0.00106M%'
formatNumber(-Infinity); // '-∞'
formatNumber(NaN); // ''
formatNumber(NaN, {valueIfNaN: NaN}); // NaN
Function
/*
* Return the given number as a formatted string. The default format is a plain
* integer with thousands-separator commas. The optional parameters facilitate
* other formats:
* - decimals = the number of decimals places to round to and show
* - valueIfNaN = the value to show for non-numeric input
* - style
* - '%': multiplies by 100 and appends a percent symbol
* - '$': prepends a dollar sign
* - useOrderSuffix = whether to use suffixes like k for 1,000, etc.
* - orderSuffixes = the list of suffixes to use
* - minOrder and maxOrder allow the order to be constrained. Examples:
* - minOrder = 1 means the k suffix should be used for numbers < 1,000
* - maxOrder = 1 means the k suffix should be used for numbers >= 1,000,000
*/
function formatNumber(number, {
decimals = 0,
valueIfNaN = '',
style = '',
useOrderSuffix = false,
orderSuffixes = ['', 'k', 'M', 'B', 'T'],
minOrder = 0,
maxOrder = Infinity
} = {}) {
let x = parseFloat(number);
if (isNaN(x))
return valueIfNaN;
if (style === '%')
x *= 100.0;
let order;
if (!isFinite(x) || !useOrderSuffix)
order = 0;
else if (minOrder === maxOrder)
order = minOrder;
else {
const unboundedOrder = Math.floor(Math.log10(Math.abs(x)) / 3);
order = Math.max(
0,
minOrder,
Math.min(unboundedOrder, maxOrder, orderSuffixes.length - 1)
);
}
const orderSuffix = orderSuffixes[order];
if (order !== 0)
x /= Math.pow(10, order * 3);
return (style === '$' ? '$' : '') +
x.toLocaleString(
'en-US',
{
style: 'decimal',
minimumFractionDigits: decimals,
maximumFractionDigits: decimals
}
) +
orderSuffix +
(style === '%' ? '%' : '');
}
Solution 32 - Javascript
Wow there are so many answers on here. I thought I would give you how I solved it as it seemed to be the easiest to read, handles negative numbers, and goes out far in the kilo number range for JavaScript. It also would be easy to change to what you want or extended even farther.
const symbols = [
{ value: 1, symbol: '' },
{ value: 1e3, symbol: 'k' },
{ value: 1e6, symbol: 'M' },
{ value: 1e9, symbol: 'G' },
{ value: 1e12, symbol: 'T' },
{ value: 1e15, symbol: 'P' },
{ value: 1e18, symbol: 'E' }
];
function numberFormatter(num, digits) {
const numToCheck = Math.abs(num);
for (let i = symbols.length - 1; i >= 0; i--) {
if (numToCheck >= symbols[i].value) {
const newNumber = (num / symbols[i].value).toFixed(digits);
return `${newNumber}${symbols[i].symbol}`;
}
}
return '0';
}
const tests = [
{ num: 1234, digits: 1 },
{ num: 100000000, digits: 1 },
{ num: 299792458, digits: 1 },
{ num: 759878, digits: 1 },
{ num: -759878, digits: 0 },
{ num: 123, digits: 1 },
{ num: 123.456, digits: 1 },
{ num: -123.456, digits: 2 },
{ num: 123.456, digits: 4 }
];
for (let i = 0; i < tests.length; i++) {
console.log(`numberFormatter(${tests[i].num}, ${tests[i].digits})=${numberFormatter(tests[i].num, tests[i].digits)}`);
}
Solution 33 - Javascript
A shorter alternative :
function nFormatter(num) {
const format = [
{ value: 1e18, symbol: 'E' },
{ value: 1e15, symbol: 'P' },
{ value: 1e12, symbol: 'T' },
{ value: 1e9, symbol: 'G' },
{ value: 1e6, symbol: 'M' },
{ value: 1e3, symbol: 'k' },
{ value: 1, symbol: '' },
];
const formatIndex = format.findIndex((data) => num >= data.value);
console.log(formatIndex)
return (num / format[formatIndex === -1? 6: formatIndex].value).toFixed(2) + format[formatIndex === -1?6: formatIndex].symbol;
}
Solution 34 - Javascript
Here is my version of Waylon Flinn's answer. This removes the .0 and fixes an undefined when the tier is not exactly an integer.
const SI_SYMBOL = ['', 'k', 'M', 'G', 'T', 'P', 'E'];
abbreviateNumber(num) {
const tier = Math.floor(Math.log10(num) / 3) || 0;
let result = '' + num;
// if zero, we don't need a suffix
if (tier > 0) {
// get suffix and determine scale
const suffix = SI_SYMBOL[tier];
const scale = Math.pow(10, tier * 3);
// scale the number
const scaled = num / scale;
// format number and add suffix
result = scaled.toFixed(1).replace('.0', '') + suffix;
}
return result;
}
Solution 35 - Javascript
Well, you can use the simplest way around.
$('#attrib-id').val(Number(response.column/1000000).toLocaleString()); // Million
You can use for other properties by dividing the value by the number you want like if you want to display "K" in front of a number, you should go for Number(response.column/1000)
, and the rest of the things accordingly.