# Format a number as 2.5K if a thousand or more, otherwise 900

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?

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``````

``````/**
* 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.

# 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) {
var SI_POSTFIXES = ["", "k", "M", "G", "T", "P", "E"];
var tier = Math.log10(Math.abs(number)) / 3 | 0;
if(tier == 0) return number;
var postfix = SI_POSTFIXES[tier];
var scale = Math.pow(10, tier * 3);
var scaled = number / scale;
var formatted = scaled.toFixed(1) + '';
if (/\.0\$/.test(formatted))
formatted = formatted.substr(0, formatted.length - 2);
return formatted + postfix;
}
``````

jsFiddle with test cases -> https://jsfiddle.net/xyug4nvz/7/

A lot of answers on this thread get rather complicated, using Math objects, map objects, for-loops, regex, etc. But these approaches don't really improve the readability of the code, or the performance. A straight forward approach seems to offer the best design.

## 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));``````

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"
``````

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

http://numeraljs.com/

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
}
``````

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) {
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 }
``````
• Support negative number
• Checking for `!Number.isFinite`
• Change `' K M G T P E Z Y'` to `' K M'` if you want the max unit is `M`

Below code is 1K = 1024, if you want 1K = 1000, change all the 1024 to 1000.

``````Number.prototype.prefix = function (precision = 2) {

var units = ' K M G T P E Z Y'.split(' ');

if (this < 0) {
return '-' + Math.abs(this).prefix(precision);
}

if (this < 1) {
return this + units[0];
}

var power = Math.min(
Math.floor(Math.log(this) / Math.log(1024)),
units.length - 1
);

return (this / Math.pow(1024, power)).toFixed(precision) + units[power];
}

console.log('10240 = ' + (10240).prefix()) // 10.00K
console.log('1234000 = ' + (1234000).prefix(1)) // 1.2M
console.log('10000 = ' + (-10000).prefix()) // -9.77K``````

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;
}
``````

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;
}
``````
``````/*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;
}
``````

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);``````

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;
}
``````

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 === '%' ? '%' : '');
}
``````

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)}`);
}``````

Not satisfied any of the posted solutions, so here's my version:

1. Supports positive and negative numbers
2. Supports negative exponents
3. Rounds up to next exponent if possible
4. Performs bounds checking (doesn't error out for very large/small numbers)
5. Strips off trailing zeros/spaces
6. 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]) );
}``````

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))``````

A more generalized version:

``````function nFormatter(num, digits) {
var si = [
{ 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" }
];
var rx = /\.0+\$|(\.[0-9]*[1-9])0+\$/;
var i;
for (i = si.length - 1; i > 0; i--) {
if (num >= si[i].value) {
break;
}
}
return (num / si[i].value).toFixed(digits).replace(rx, "\$1") + si[i].symbol;
}

/*
* Tests
*/
var 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 }
];
var i;
for (i = 0; i < tests.length; i++) {
console.log("nFormatter(" + tests[i].num + ", " + tests[i].digits + ") = " + nFormatter(tests[i].num, tests[i].digits));
}``````

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(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

What does `SI` stand for?

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

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"
``````

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"
``````

### 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) }`));``````

ES2020 adds support for this in `Intl.NumberFormat` Using notation as follows:

``console.log(Intl.NumberFormat('en-US', { notation: "compact" , compactDisplay: "short" }).format(987654321));``

`NumberFormat` specs:

Note that at the moment not all browsers support ES2020, so you may need to this Polyfill: https://www.npmjs.com/package/@formatjs/intl-unified-numberformat

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.

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
``````

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;
}
``````