Philipp Lenssen
Philipp Lenssen

Reputation: 9218

Convert long number into abbreviated string in JavaScript, with a special shortness requirement

In JavaScript, how would one write a function that converts a given [edit: positive integer] number (below 100 billion) into a 3-letter abbreviation -- where 0-9 and a-z/A-Z are counting as a letter, but the dot (as it's so tiny in many proportional fonts) would not, and would be ignored in terms of the letter limit?

This question is related to this helpful thread, but it's not the same; for instance, where that function would turn e.g. "123456 -> 1.23k" ("123.5k" being 5 letters) I am looking for something that does "123456 -> 0.1m" ("0[.]1m" being 3 letters). For instance, this would be the output of hoped function (left original, right ideal return value):

0                      "0"
12                    "12"
123                  "123"
1234                "1.2k"
12345                "12k"
123456              "0.1m"
1234567             "1.2m"
12345678             "12m"
123456789           "0.1b"
1234567899          "1.2b"
12345678999          "12b"

Thanks!

Update: Thanks! An answer is in and works per the requirements when the following amendments are made:

function abbreviateNumber(value) {
    var newValue = value;
    if (value >= 1000) {
        var suffixes = ["", "k", "m", "b","t"];
        var suffixNum = Math.floor( (""+value).length/3 );
        var shortValue = '';
        for (var precision = 2; precision >= 1; precision--) {
            shortValue = parseFloat( (suffixNum != 0 ? (value / Math.pow(1000,suffixNum) ) : value).toPrecision(precision));
            var dotLessShortValue = (shortValue + '').replace(/[^a-zA-Z 0-9]+/g,'');
            if (dotLessShortValue.length <= 2) { break; }
        }
        if (shortValue % 1 != 0)  shortValue = shortValue.toFixed(1);
        newValue = shortValue+suffixes[suffixNum];
    }
    return newValue;
}

Upvotes: 130

Views: 102952

Answers (22)

tim-montague
tim-montague

Reputation: 17372

Approach 1: Built-in library

I would recommend using Javascript's built-in library method Intl.NumberFormat

const formatCash = Intl.NumberFormat('en-US', {
  notation: "compact",
  maximumFractionDigits: 1
}).format(2500);

console.log(formatCash);

Approach 2: No library

But you can also create these abbreviations with simple if statements, and without the complexity of Math, maps, regex, 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;
  // Could use 'if (n < 1e6)' if you like
  if (n >= 1e3 && n < 1e6) return +(n / 1e3).toFixed(1) + "K";
  // Could use 'if (n < 1e9)' if you like
  if (n >= 1e6 && n < 1e9) return +(n / 1e6).toFixed(1) + "M";
  // Could use 'if (n < 1e12)' if you like
  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);
}

Upvotes: 124

Everything Digital
Everything Digital

Reputation: 191

Here's an example leveraging the toLocaleString which will add commas. Many ways to customize this, but i found this to be straightforward for me.

console.log(
  [
    0,
    12,
    123,
    1234,
    12345,
    123456,
    1234567,
    12345678,
    123456789,
    1234567899,
    12345678999,
  ].map(m => formatLargeNumber(m,0))
);

function formatLargeNumber(num,numberOfSecondaryNumbers) {
  if (isNaN(num)) return num;
  const match = {
    2: 'k',
    3: 'M',
    4: 'B',
    5: 'T',
  };

  const numbersSplitByComma = num.toLocaleString('en-US', { maximumFractionDigits: 0 }).split(',');
  const magnitude = numbersSplitByComma.length;
  const matched = match[magnitude];

  const primary = numbersSplitByComma[0];
  const secondary = numbersSplitByComma[1]?.slice(0,numberOfSecondaryNumbers);

   if(matched) return `${primary}${secondary && secondary !== '0' ? '.' + secondary : ''}${matched}`;
  return num;
}

Upvotes: 0

James L.
James L.

Reputation: 14515

The modern, easy, built-in, highly customizable, and 'no-code' way: Intl.FormatNumber 's format function (compatibility graph)

var numbers = [98721, 9812730,37462,29,093484620123, 9732,0283737718234712]
for(let num of numbers){
  console.log(new Intl.NumberFormat( 'en-US', { maximumFractionDigits: 1,notation: "compact" , compactDisplay: "short" }).format(num));
}
98.7K
9.8M
37.5K
29
93.5B
9.7K
283.7T

Notes:

Upvotes: 36

Mario Dav&#243;
Mario Dav&#243;

Reputation: 31

This is another take on it. It replicates YT subscriber count abbreviation.

function countAbbreviation(count) {
    const COUNT_ABBRS = ["", "K", "M", "B", "T"];
    if (count < 1000) {
        return count;
    }
    const i = Math.floor(Math.log(count) / Math.log(1000));
    let result = count / (1000 ** i);
    const digits = Math.floor(Math.log10(result)) + 1;
    const decimals = Math.max(0, 3 - digits);
    result = result.toFixed(decimals);
    result = result + COUNT_ABBRS[i];
    return result;
}


console.log(countAbbreviation(102))
console.log(countAbbreviation(1002))
console.log(countAbbreviation(10002))
console.log(countAbbreviation(100002))
console.log(countAbbreviation(1000002))
console.log(countAbbreviation(10000002))
console.log(countAbbreviation(100000002))
console.log(countAbbreviation(1000000002))

// 102
// 1.00K
// 10.0K
// 100K
// 1.00M
// 10.0M

Upvotes: 1

PhanhotboY
PhanhotboY

Reputation: 1

here's the Recursive and shorter version using Pure JS for those who are interested:

const abbCharacters = ['', 'K', 'M', 'B', 'T'];
const shortenNumber = (num, stack = 0) => {
  if (Math.abs(num) < 1000 || stack >= abbCharacters.length - 1) return num + abbCharacters[stack];

  return shortenNumber(Math.round(num / 1000), ++stack);
};

Result:

console.log(shortenNumber(100)); //100
console.log(shortenNumber(-100)); //-100
console.log(shortenNumber(9023)); //9k
console.log(shortenNumber(-9023)); //-9k
console.log(shortenNumber(213423)); //213k
console.log(shortenNumber(-23945523)); //-24M
console.log(shortenNumber(5555232323549455)); //5555T
console.log(shortenNumber(-5555232323549455)); //-5555T

Upvotes: 0

mahshad
mahshad

Reputation: 23

Try it :

const unitlist = ['', 'K', 'M', 'B']
export function AmountConveter (number: number) {
  const sign = Math.sign(number)
  let unit = 0

  while (Math.abs(number) > 1000) {
    unit = unit + 1
    number = Math.floor(Math.abs(number) / 100) / 10
  }
  return sign * Math.abs(number) + unitlist[unit]
}

Upvotes: 1

Stefan Gabos
Stefan Gabos

Reputation: 1471

Here's another take on it. I wanted 123456 to be 123.4K instead of 0.1M

UPDATE 2022, Dec. 5

Added support for negative values and non-integer values

function convert(value) {

    var length = (Math.abs(parseInt(value, 10)) + '').length,
        index = Math.ceil((length - 3) / 3),
        suffix = ['K', 'M', 'B', 'T'];

    if (length < 4) return value;
    
    return (value / Math.pow(1000, index))
           .toFixed(1)
           .replace(/\.0$/, '') + suffix[index - 1];

}

var tests = [1234, 7890, -990123467, 123456, 750000.1234, 567890, 800001, 2000000, 20000000, 201234567, 801234567, 1201234567];
for (var i in tests)
    document.writeln('<p>convert(' + tests[i] + ') = ' + convert(tests[i]) + '</p>');

Upvotes: 4

Monwell Partee
Monwell Partee

Reputation: 718

Pure Javascript


n --> 292234567890 to 292,234,567,890
s --> 292,234,567,890 to 292,234,567,890 + K | M | B | T | q | Q | s | S | o | n | d | U
s --> 292,234,567,890B to 292.2B
return --> Remove 4th digit 292.2B to 292B


function format(n) {n=n.toLocaleString();
  let s = n+('KMBTqQsSondU'.split('')[n.split(',').length-2]||'')
  s = s.replace(/,([1-9])[\d,.]+|,[\d,.]+/g,(m,a)=>a?'.'+a:'')
  return s.replace(/(\d{3})\.\d/, '$1');
}


//Just for show
let negative = [-1991078910902345678907890, -991708910902345678907890,-10902345678907890, -1000234567890, -1234567890, -12345678, -1234567, -12345, -1234, -123, -12, -1, 0]
let positive = [1991078910902345678907890, 991078910902345678907890,10902345678907890, 1000234567890, 1234567890, 12345678, 1234567, 12345, 1234, 123, 12, 1, 0]
let table = '<table cellspacing="0"><tbody>';
negative.forEach(function(x){ table += '<tr><td style="padding-right: 30px;">'+x+'</td><td>'+ format(x)+'</td></tr>'})
table +='</tbody></table><table cellspacing="0"><tbody>'
positive.forEach(function(x){ table += '<tr><td style="padding-right: 30px;">'+x+'</td><td>'+ format(x)+'</td></tr>'})
document.body.innerHTML = table+'</tbody></table>';
tr:nth-child(odd) {background: #f8f8f8;}
td {padding: 5px 10px;}
table {
  font-size: 13px;
  display: inline-table;
  padding-right: 30px;
}

Pure Javascript

Pros: Native Built in Solution
Cons: Maxes out at Trillion

function format(x) {let o={maximumFractionDigits: 1,notation: "compact",compactDisplay: "short"};
  let a=x<0,n=x*Math.sign(x);s=new Intl.NumberFormat('en-US', o).format(n);return a?'-'+s:s;
}



//Just for show
let negative = [-1991078910902345678907890, -991078910902345678907890,-10902345678907890, -1000234567890, -1234567890, -12345678, -1234567, -12345, -1234, -123, -12, -1, 0]
let positive = [1991078910902345678907890, 991078910902345678907890,10902345678907890, 1000234567890, 1234567890, 12345678, 1234567, 12345, 1234, 123, 12, 1, 0]
let table = '<table cellspacing="0"><tbody>';
negative.forEach(function(x){ table += '<tr><td style="padding-right: 10px;">'+x+'</td><td>'+ format(x)+'</td></tr>'})
table +='</tbody></table><table cellspacing="0"><tbody>'
positive.forEach(function(x){ table += '<tr><td style="padding-right: 10px;">'+x+'</td><td>'+ format(x)+'</td></tr>'})
document.body.innerHTML = table+'</tbody></table>';
tr:nth-child(odd) {background: #f8f8f8;}
td {padding: 5px 10px;}
table {
  font-size: 12px;
  display: inline-table;
  padding-right: 10px;
}

Upvotes: -2

oooooo
oooooo

Reputation: 11

Even more Abbreviation?

Let's make "Qa" as Quadrillions and "Qi" as Quintillions... maybe "Sx" Sextillions, and So on...

if (num >= 1e3 !& num >= 1e6) {num2 = num/1e3 + "K";};
if (num >= 1e6 !& num >= 1e9) {num2 = num/1e6 + "M";};
if (num >= 1e9 !& num >= 1e12) {num2 = num/1e9 + "B";};
if (num >= 1e12 !& num >= 1e15) {num2 = num/1e12 + "T";};
if (num >= 1e15 !& num >= 1e18) {num2 = num/1e15 + "Qa";};
if (num >= 1e18 !& num >= 1e21) {num2 = num/1e18 + "Qi";};
if (num >= 1e21 !& num >= 1e24) {num2 = num/1e21 + "Sx";};
if (num >= 1e24 !& num >= 1e27) {num2 = num/1e24 + "Sp";};
if (num >= 1e27 !& num >= 1e30) {num2 = num/1e27 + "Oc";};
if (num >= 1e30 !& num >= 1e93) {num2 = num/1e30 + "No";};
if (num >= 1e33 !& num >= 1e36) {num2 = num/1e33 + "Dc";};
if (num >= 1e36 !& num >= 1e39) {num2 = num/1e36 + "UDc";};
if (num >= 1e39) {num2 = num/1e39 + "DDc";};

Upvotes: 0

chethankumar
chethankumar

Reputation: 422

Indian Currency format to (K, L, C) Thousand, Lakh, Crore

const formatCash = n => {
  if (n < 1e3) return n;
  if (n >= 1e3 && n < 1e5) return +(n / 1e3).toFixed(1) + "K";
  if (n >= 1e5 && n <= 1e6) return +(n / 1e5).toFixed(1) + "L";
  if (n >= 1e6 && n <= 1e9) return +(n / 1e7).toFixed(1) + "C";
};

Upvotes: 1

Vixson
Vixson

Reputation: 729

Use as a Number Prototype

For easy and direct you. Simply make a prototype of it. Here is an example.

Number.prototype.abbr = function (decimal = 2): string {
  const notations = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'],
    i = Math.floor(Math.log(this) / Math.log(1000));
  return `${parseFloat((this / Math.pow(1000, i)).toFixed(decimal))}${notations[i]}`;
};

Upvotes: 1

chucktator
chucktator

Reputation: 1856

I believe ninjagecko's solution doesn't quite conform with the standard you wanted. The following function does:

function intToString (value) {
    var suffixes = ["", "k", "m", "b","t"];
    var suffixNum = Math.floor((""+value).length/3);
    var shortValue = parseFloat((suffixNum != 0 ? (value / Math.pow(1000,suffixNum)) : value).toPrecision(2));
    if (shortValue % 1 != 0) {
        shortValue = shortValue.toFixed(1);
    }
    return shortValue+suffixes[suffixNum];
}

For values greater than 99 trillion no letter will be added, which can be easily fixed by appending to the 'suffixes' array.

Edit by Philipp follows: With the following changes it fits with all requirements perfectly!

function abbreviateNumber(value) {
    var newValue = value;
    if (value >= 1000) {
        var suffixes = ["", "k", "m", "b","t"];
        var suffixNum = Math.floor( (""+value).length/3 );
        var shortValue = '';
        for (var precision = 2; precision >= 1; precision--) {
            shortValue = parseFloat( (suffixNum != 0 ? (value / Math.pow(1000,suffixNum) ) : value).toPrecision(precision));
            var dotLessShortValue = (shortValue + '').replace(/[^a-zA-Z 0-9]+/g,'');
            if (dotLessShortValue.length <= 2) { break; }
        }
        if (shortValue % 1 != 0)  shortValue = shortValue.toFixed(1);
        newValue = shortValue+suffixes[suffixNum];
    }
    return newValue;
}

Upvotes: 88

Rishabh
Rishabh

Reputation: 101

@nimesaram

Your solution will not be desirable for the following case:

Input 50000
Output 50.0k

Following solution will work fine.

const convertNumberToShortString = (
  number: number,
  fraction: number
) => {
  let newValue: string = number.toString();
  if (number >= 1000) {
    const ranges = [
      { divider: 1, suffix: '' },
      { divider: 1e3, suffix: 'k' },
      { divider: 1e6, suffix: 'm' },
      { divider: 1e9, suffix: 'b' },
      { divider: 1e12, suffix: 't' },
      { divider: 1e15, suffix: 'p' },
      { divider: 1e18, suffix: 'e' }
    ];
    //find index based on number of zeros
    const index = Math.floor(Math.abs(number).toString().length / 3);
    let numString = (number / ranges[index].divider).toFixed(fraction);
    numString =
      parseInt(numString.substring(numString.indexOf('.') + 1)) === 0
        ? Math.floor(number / ranges[index].divider).toString()
        : numString;
    newValue = numString + ranges[index].suffix;
  }
  return newValue;
};

// Input 50000
// Output 50k
// Input 4500
// Output 4.5k

Upvotes: 0

Nimer Awad
Nimer Awad

Reputation: 4199

I'm using this function to get these values.

function Converter(number, fraction) {
    let ranges = [
      { divider: 1, suffix: '' },
      { divider: 1e3, suffix: 'K' },
      { divider: 1e6, suffix: 'M' },
      { divider: 1e9, suffix: 'G' },
      { divider: 1e12, suffix: 'T' },
      { divider: 1e15, suffix: 'P' },
      { divider: 1e18, suffix: 'E' },
    ]
    //find index based on number of zeros
    let index = (Math.abs(number).toString().length / 3).toFixed(0)
    return (number / ranges[index].divider).toFixed(fraction) + ranges[index].suffix
}

Each 3 digits has different suffix, that's what i'm trying to find firstly.

So, remove negative symbol if exists, then find how many 3 digits in this number.

after that find appropriate suffix based on previous calculation added to divided number.

Converter(1500, 1)

Will return:

1.5K

Upvotes: 1

danilowoz
danilowoz

Reputation: 111

Code

const SI_PREFIXES = [
  { 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 abbreviateNumber = (number) => {
  if (number === 0) return number

  const tier = SI_PREFIXES.filter((n) => number >= n.value).pop()
  const numberFixed = (number / tier.value).toFixed(1)

  return `${numberFixed}${tier.symbol}`
}

abbreviateNumber(2000) // "2.0k"
abbreviateNumber(2500) // "2.5k"
abbreviateNumber(255555555) // "255.6M"

Test:

import abbreviateNumber from './abbreviate-number'

test('abbreviateNumber', () => {
  expect(abbreviateNumber(0)).toBe('0')
  expect(abbreviateNumber(100)).toBe('100')
  expect(abbreviateNumber(999)).toBe('999')

  expect(abbreviateNumber(1000)).toBe('1.0k')
  expect(abbreviateNumber(100000)).toBe('100.0k')
  expect(abbreviateNumber(1000000)).toBe('1.0M')
  expect(abbreviateNumber(1e6)).toBe('1.0M')
  expect(abbreviateNumber(1e10)).toBe('10.0G')
  expect(abbreviateNumber(1e13)).toBe('10.0T')
  expect(abbreviateNumber(1e16)).toBe('10.0P')
  expect(abbreviateNumber(1e19)).toBe('10.0E')

  expect(abbreviateNumber(1500)).toBe('1.5k')
  expect(abbreviateNumber(1555)).toBe('1.6k')

  expect(abbreviateNumber(undefined)).toBe('0')
  expect(abbreviateNumber(null)).toBe(null)
  expect(abbreviateNumber('100')).toBe('100')
  expect(abbreviateNumber('1000')).toBe('1.0k')
})

Upvotes: 5

NuSkooler
NuSkooler

Reputation: 5525

Here's what I think is a fairly elegant solution. It does not attempt to deal with negative numbers:

const COUNT_ABBRS = [ '', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' ];

function formatCount(count, withAbbr = false, decimals = 2) {
    const i     = 0 === count ? count : Math.floor(Math.log(count) / Math.log(1000));
    let result  = parseFloat((count / Math.pow(1000, i)).toFixed(decimals));
    if(withAbbr) {
        result += `${COUNT_ABBRS[i]}`; 
    }
    return result;
}

Examples:

   formatCount(1000, true);
=> '1k'
   formatCount(100, true);
=> '100'
   formatCount(10000, true);
=> '10k'
   formatCount(10241, true);
=> '10.24k'
   formatCount(10241, true, 0);
=> '10k'
   formatCount(10241, true, 1)
=> '10.2k'
   formatCount(1024111, true, 1)
=> '1M'
   formatCount(1024111, true, 2)
=> '1.02M'

Upvotes: 19

Pasupol Bunsaen
Pasupol Bunsaen

Reputation: 1

            function converse_number (labelValue) {

                    // Nine Zeroes for Billions
                    return Math.abs(Number(labelValue)) >= 1.0e+9

                    ? Math.abs(Number(labelValue)) / 1.0e+9 + "B"
                    // Six Zeroes for Millions 
                    : Math.abs(Number(labelValue)) >= 1.0e+6

                    ? Math.abs(Number(labelValue)) / 1.0e+6 + "M"
                    // Three Zeroes for Thousands
                    : Math.abs(Number(labelValue)) >= 1.0e+3

                    ? Math.abs(Number(labelValue)) / 1.0e+3 + "K"

                    : Math.abs(Number(labelValue));

                }

alert(converse_number(100000000000));

Upvotes: 0

Priyanshu Chauhan
Priyanshu Chauhan

Reputation: 5535

Intl is the Javascript standard 'package' for implemented internationalized behaviours. Intl.NumberFormatter is specifically the localized number formatter. So this code actually respects your locally configured thousands and decimal separators.

intlFormat(num) {
    return new Intl.NumberFormat().format(Math.round(num*10)/10);
}

abbreviateNumber(value) {
    let num = Math.floor(value);
    if(num >= 1000000000)
        return this.intlFormat(num/1000000000)+'B';
    if(num >= 1000000)
        return this.intlFormat(num/1000000)+'M';
    if(num >= 1000)
        return this.intlFormat(num/1000)+'k';
    return this.intlFormat(num);
}

abbreviateNumber(999999999999) // Gives 999B

Related question: Abbreviate a localized number in JavaScript for thousands (1k) and millions (1m)

Upvotes: 1

HoangLong85
HoangLong85

Reputation: 287

I think you cant try this numeraljs/

If you want convert 1000 to 1k

console.log(numeral(1000).format('0a'));

and if you want convert 123400 to 123.4k try this

console.log(numeral(123400).format('0.0a'));

Upvotes: 13

MichaelJones
MichaelJones

Reputation: 1406

After some playing around, this approach seems to meet the required criteria. Takes some inspiration from @chuckator's answer.

function abbreviateNumber(value) {

    if (value <= 1000) {
        return value.toString();
    }

    const numDigits = (""+value).length;
    const suffixIndex = Math.floor(numDigits / 3);

    const normalisedValue = value / Math.pow(1000, suffixIndex);

    let precision = 2;
    if (normalisedValue < 1) {
        precision = 1;
    }

    const suffixes = ["", "k", "m", "b","t"];
    return normalisedValue.toPrecision(precision) + suffixes[suffixIndex];
}

Upvotes: 1

D.Deriso
D.Deriso

Reputation: 4397

This handles very large values as well and is a bit more succinct and efficient.

abbreviate_number = function(num, fixed) {
  if (num === null) { return null; } // terminate early
  if (num === 0) { return '0'; } // terminate early
  fixed = (!fixed || fixed < 0) ? 0 : fixed; // number of decimal places to show
  var b = (num).toPrecision(2).split("e"), // get power
      k = b.length === 1 ? 0 : Math.floor(Math.min(b[1].slice(1), 14) / 3), // floor at decimals, ceiling at trillions
      c = k < 1 ? num.toFixed(0 + fixed) : (num / Math.pow(10, k * 3) ).toFixed(1 + fixed), // divide by power
      d = c < 0 ? c : Math.abs(c), // enforce -0 is 0
      e = d + ['', 'K', 'M', 'B', 'T'][k]; // append power
  return e;
}

Results:

for(var a='', i=0; i < 14; i++){ 
    a += i; 
    console.log(a, abbreviate_number(parseInt(a),0)); 
    console.log(-a, abbreviate_number(parseInt(-a),0)); 
}

0 0
-0 0
01 1
-1 -1
012 12
-12 -12
0123 123
-123 -123
01234 1.2K
-1234 -1.2K
012345 12.3K
-12345 -12.3K
0123456 123.5K
-123456 -123.5K
01234567 1.2M
-1234567 -1.2M
012345678 12.3M
-12345678 -12.3M
0123456789 123.5M
-123456789 -123.5M
012345678910 12.3B
-12345678910 -12.3B
01234567891011 1.2T
-1234567891011 -1.2T
0123456789101112 123.5T
-123456789101112 -123.5T
012345678910111213 12345.7T
-12345678910111212 -12345.7T

Upvotes: 59

ninjagecko
ninjagecko

Reputation: 91094

Based on my answer at https://stackoverflow.com/a/10600491/711085 , your answer is actually slightly shorter to implement, by using .substring(0,3):

function format(n) {
    with (Math) {
        var base = floor(log(abs(n))/log(1000));
        var suffix = 'kmb'[base-1];
        return suffix ? String(n/pow(1000,base)).substring(0,3)+suffix : ''+n;
    }
}

(As usual, don't use Math unless you know exactly what you're doing; assigning var pow=... and the like would cause insane bugs. See link for a safer way to do this.)

> tests = [-1001, -1, 0, 1, 2.5, 999, 1234, 
           1234.5, 1000001, Math.pow(10,9), Math.pow(10,12)]
> tests.forEach(function(x){ console.log(x,format(x)) })

-1001 "-1.k"
-1 "-1"
0 "0"
1 "1"
2.5 "2.5"
999 "999"
1234 "1.2k"
1234.5 "1.2k"
1000001 "1.0m"
1000000000 "1b"
1000000000000 "1000000000000"

You will need to catch the case where the result is >=1 trillion, if your requirement for 3 chars is strict, else you risk creating corrupt data, which would be very bad.

Upvotes: 7

Related Questions