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?
-
3Do you also need `M` and `G`? – Salman A Feb 27 '12 at 07:59
-
I will need M yes...Can you help? – Carl Weis Feb 27 '12 at 08:13
-
2see http://stackoverflow.com/questions/17633462/format-a-javascript-number-with-a-metric-prefix-like-1-5k-1m-1g-etc – magritte Jul 13 '13 at 20:48
-
2See https://stackoverflow.com/a/60988355/80428 for a locale friendly ES2020 solution – Jay Wick May 20 '21 at 09:35
36 Answers
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));
});

- 262,204
- 82
- 430
- 521
-
1@SalmanA - Great help, it fails if one pass arg as string, if cleansed with parseFloat works well. Thank you! – Adesh M Apr 25 '16 at 06:57
-
3Small fix for numbers less < 1000, add {value: 1E0, symbol: ""} to var si = – Dimmduh Aug 11 '16 at 10:09
-
2@GiovanniAzua just replace `if (num >= si[i].value)` with `if (Math.abs(num) >= si[i].value)` – Salman A May 22 '17 at 07:27
-
-
1@M.Octavio the regex is used to trim trailing zeros e.g. `1.0` becomes `1` and `1.10` becomes `1.1` – Salman A Aug 27 '18 at 20:17
-
1To account for negative values use `Math.abs(num) >= si[i].value` in the if statement inside the loop – Devtician Jun 25 '20 at 22:30
-
2also, it might be great to treat the special case at the beginning. if(num === 0) return 0; – Raul Jun 03 '21 at 23:24
-
-
Great solution, but this doesn't account for negative numbers. Trying to figure out how. – RukshanJS May 15 '22 at 20:05
-
-
UPDATE : I added a simple `if (num<0)` and then added a "-" sign infront of the returned value if it is, to account for negative numbers. Had to use another variable though. – RukshanJS May 15 '22 at 21:04
-
I think the abbreviation for billion is B - https://abbreviations.yourdictionary.com/different-abbreviations-thousand-million-billion – John Meyer Jul 27 '22 at 17:49
-
@john the original version of answer used SI prefixes (https://en.m.wikipedia.org/wiki/Metric_prefix). Billion is Giga. Of course you can change it. – Salman A Jul 27 '22 at 18:57
-
-
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

- 11,291
- 4
- 29
- 45

- 16,785
- 5
- 53
- 66
-
7Minor fix suggested... Should be lowercase k for thousands. Upper is for Kilos. Tried to edit, but requires at least 6 characters changed before it will take. – Adam Youngers Dec 19 '14 at 18:47
-
How do I inset a php variable inside here and use it? i.e. if my number variable is `$mynumber_output` where do I insert this to use it? For example, say `$mynumber_output` = 12846, I would like 12846 converted to `12.8k` – Feb 08 '17 at 23:13
-
Note that one kilobyte is 1024 bytes in some cases: https://en.wikipedia.org/wiki/Kilobyte – Olle Härstedt May 01 '17 at 00:01
-
-
6Doesn't completely answer the user's question. "I will need M yes...Can you help?" - Carl Weis – tim-montague May 04 '19 at 22:54
-
Why is it that when a typical developers writes javascript code they think it is suddenly OK to perform the same calculation more than once (twice, three times...) ? why is Math.abs(num) called twice ? – Cesar Feb 04 '20 at 19:20
-
11`Math.round(Math.abs(num)/100)/10` instead of `(Math.abs(num)/1000).toFixed(1)` so typescript is happy – Pierre de LESPINAY Jun 18 '20 at 09:47
-
I'm afraid that I'm missing the point, but I think this example has unneeded function calls. Why not just return this way? `return Math.abs(num) > 999 ? (num/1000).toFixed(1) + 'k' : num` – André Sousa Oct 20 '20 at 18:58
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

- 3,593
- 2
- 22
- 37
-
1That package has been deprecated, so please use this link: https://www.npmjs.com/package/@formatjs/intl-numberformat – Ammad Khalid May 30 '20 at 07:42
-
7Note: Chrome supports the `notation` and `compactDisplay` but FireFox 77 and Safari 13.1 still do not support it so you'll likely need the polyfill. – Josh Unger Jun 04 '20 at 03:06
-
1Wow, Firefox *just* added support for this in v. 78, it seems. Of course, 2+ years from now, this comment's going to look stupid. :P (It's funny to me though because the code runs for me but it doesn't convert properly, so I'll need to do an update.) – Andrew Jul 07 '20 at 18:51
-
-
Eg. For german compact, when you want M for million, it does not give M, but rather a german specific alternative. ```const number = 12453456.789; console.log(new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR', notation:'compact' }).format(number)); ``` // 12 Mio. € – AnandShiva Oct 26 '21 at 08:51
-
Also for Germany and some language's any number in thousand's will not have compact. But it will be displayed as such – AnandShiva Oct 26 '21 at 08:52
-
3Note the above example formats `12345` as `12K` and not `12.3K`. You can add `maximumSignificantDigits` or `maximumFractionDigits`, depending on the behaviour you want. eg `Intl.NumberFormat("en", { notation: "compact", maximumSignificantDigits: 3 }).format(12345) === "12.3K"` or `Intl.NumberFormat("en", { notation: "compact", maximumFractionDigits: 1 }).format(12345) === "12.3K"` – Rik Jan 15 '23 at 20:28
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

- 19,969
- 15
- 70
- 72
-
I really like your solution. To be able to shorten negative values as well, I multiply the number by -1 before and after determining the tier, since Math.log10(negativeValue) would return NaN. – xhadon Jun 14 '17 at 10:26
-
3Just use `Math.abs` to add support to negative numbers, like that: `var tier = Math.log10(Math.abs(number)) / 3 | 0;`. – Caio Tarifa Jul 13 '20 at 05:19
-
-
-
1Thanks, that's actually the most understandable answer, in terms of what's happening. – Fabian Jan 15 '22 at 20:12
-
Yea, this one makes a lot more sense and is much easier to read, especially with the comments. It also works with negative numbers too, which is a plus. – train Mar 25 '22 at 21:09
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

- 2,153
- 2
- 16
- 11
-
3Anyway to do this without rounding the number? 1,590,000 will return 1.6M. – Brett Hardin Sep 30 '14 at 17:48
-
4Sometimes its hard to know when to post a new answer of edit an existing one, something I use to decide is if I steal the code from another users answer, I usually edit their answer so that they can get the recognition instead of me stealing their code. – M H Feb 19 '16 at 17:09
-
@Yash you're the code I'm trying to implement in the counter script but not getting this is my codepen link https://codepen.io/Merajkhan/pen/MMoxGE?editors=1010 Can you help me out how to implement this logic I want K, L, M units have to come. – Mehraj Khan Jun 25 '19 at 07:34
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);
}

- 16,217
- 5
- 62
- 51
-
1@Jan - Updated my post with an example, but felt it was simple enough to compute the negative form using `'-' + formatCash(-1 * number)` – tim-montague Apr 03 '20 at 10:14
/**
* 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.

- 829
- 11
- 6
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/

- 25,132
- 12
- 90
- 84
-
1There's still an annoying bug: `abbreviateNumber(999999) == '1000k'` instead of `'1M'`. This is because `toFixed()` also rounds the numbers. Not sure how to fix it, though :/ – Vitor Baptista Sep 07 '17 at 11:24
-
@VitorBaptista If `toFixed()` rounds the number anyway, you might as well round the number before sending it to `abbreviateNumber()`, so it returns `1M` instead of `1000k`. Not a solution, but a workaround. – forsureitsme Mar 22 '18 at 19:47
-
2If you don't want rounding you can do this after the scale step: `const floored = Math.floor(scaled * 10) / 10;` – tybro0103 Apr 13 '19 at 02:24
-
1
-
1@forsureitsme sorry i haven't seen this for a year... i added your change. wrx! – King Friday Mar 02 '21 at 16:30
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"

- 13,633
- 9
- 43
- 65
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*Math.abs(number) + unitlist[unit]);
}
formatnumber(999);
formatnumber(1234);
formatnumber(12345);
formatnumber(123456);
formatnumber(1234567);
formatnumber(12345678);
formatnumber(1000);
formatnumber(-999);
formatnumber(-1234);
formatnumber(-12345);
formatnumber(-123456);
formatnumber(-1234567);
formatnumber(-12345678);

- 1,585
- 8
- 12
- 26
-
Thanks, This is helpful Because this is not a round return figure like others. – Sandeep Sherpur Jul 20 '22 at 07:55
-
1This function use a lot of resources because it's iterating over the same number again and again. My web app was freezing in Chrome and Safari and was because I was using this function several times – Victor Nov 19 '22 at 13:52
-
I think that's not with this function. I tested it with 100000 calls and nothing happened. Please share your code. – BTSM Nov 21 '22 at 01:27
-
For the number "1000" this returns "1000". To return "1K" replace the "> 1000" with ">= 1000" in the while line – NathanPB Jun 08 '23 at 19:53
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.

- 3,510
- 2
- 18
- 23
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"

- 4,964
- 3
- 31
- 38
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) }`));

- 8,670
- 7
- 63
- 89
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

- 2,433
- 32
- 24
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"

- 66,024
- 56
- 149
- 197
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)}`);
});
});

- 356
- 3
- 10
-
1Welcome to SO. Your question was flagged for 'Late Answer' review as the question is nearly 9 years old and has 32 other answers. Whilst your answer may provide some value, very late answers will often be downvoted. – GoodJuJu Dec 16 '20 at 13:43
-
2@GoodJuJu I don't see a reason why would someone "downvote" late answers. There's a lot of users who still answers late, even a user who has 78k reputation. Tell that to that guy. – Wesley Brian Lachenal Jan 15 '21 at 11:25
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

- 2,068
- 4
- 21
- 24
-
1numeraljs is not maintained anymore. The most active fork seems to be [numbro](https://github.com/foretagsplatsen/numbro). But neither of them support the SI/metric notation – Vincent de Lagabbe Nov 03 '15 at 10:36
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]) ); }

- 407
- 3
- 4
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"

- 141
- 1
- 8
-
While this code snippet may solve the problem, it doesn't explain why or how it answers the question. Please [include an explanation for your code](//meta.stackexchange.com/q/114762/269535), as that really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – Luca Kiebel Jan 12 '22 at 17:19
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');

- 1
- 62
- 391
- 407
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
}

- 149
- 1
- 6
- 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

- 16,239
- 8
- 58
- 54
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 }

- 61
- 9
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);

- 2,360
- 1
- 27
- 28
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;
}

- 1,833
- 1
- 21
- 21
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))

- 397
- 1
- 11
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;
}

- 41
- 4
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)

- 3,690
- 4
- 11
- 27
/*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;
}
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;
}

- 1,163
- 2
- 19
- 40
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 === '%' ? '%' : '');
}

- 17,541
- 8
- 92
- 91
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)}`);
}

- 502
- 2
- 14
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;
}

- 49
- 6
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.

- 159
- 1
- 6
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;
}

- 310
- 5
- 13
function AmountConveter(amount) {
return Math.abs(amount) > 999
? Math.sign(amount) * (Math.abs(amount) / 1000).toFixed(1) + "k"
: Math.sign(amount) * Math.abs(amount);
}
console.log(AmountConveter(1200)); // 1.2k
console.log(AmountConveter(-1200)); // -1.2k
console.log(AmountConveter(900)); // 900
console.log(AmountConveter(-900)); // -900

- 79
- 4