119

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;
}
LaurelT
  • 115
  • 5
Philipp Lenssen
  • 8,818
  • 13
  • 56
  • 77
  • While not JS, I've done the same in C++, which you can view at https://gist.github.com/1870641 -- the process will be the same. You might be better off looking for off-the-shelf solutions, though. – csl May 15 '12 at 11:44
  • Baz, my current start is just a mildly reformatted function from the linked thread, with mentioned issues. Before I'd try to spice up that function, I was hoping someone else might perhaps already have a smart function written somewhere, or knows how to easily do that. Csl, that's great, thanks a lot! Would that conversion also do the "0.1m" style mentioned? – Philipp Lenssen May 15 '12 at 11:48
  • I have migrated my answer to http://stackoverflow.com/a/10600491/711085 – ninjagecko May 15 '12 at 12:19
  • 9
    what's `shortNum` ? you never use is, and it's not even declared.. – vsync Oct 07 '15 at 15:11
  • 1
    Also there's a mix between `.` and `,`, so `1001.5` is turned to millions instead of thousands. – vsync Oct 07 '15 at 15:13

20 Answers20

106

Approach 1: Built-in library

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

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

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;
  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);
}
tim-montague
  • 16,217
  • 5
  • 62
  • 51
88

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;
}
Tushar Sharma
  • 192
  • 1
  • 15
chucktator
  • 1,828
  • 12
  • 16
  • Thanks! I made some amendments so it fits 100% with the requirements and edited your answer (I hope that is the correct way to do it in StackOverflow, please change if needed). Superb! – Philipp Lenssen May 15 '12 at 15:49
  • Just out of curiosity: which case/requirement did I miss? – chucktator May 15 '12 at 21:52
  • 1
    Those were minor and quickly amended based on your great answer. The following test numbers were slightly missed: 123 became 0.12k (ideal result: 123, as that's still 3 letters and thus ok); 123456 became 0.12m (ideal: 0.1m, as 0.12m is 4 letters, minus dot); same for 0.12b which with amendments now becomes 0.1b. Thanks again for your help! – Philipp Lenssen May 16 '12 at 10:00
  • 1
    I just made a small adjustment to it (yet to be peer reviewed). I added value = Math.round(value); to the very start of the function. By doing that it doesn't break when "value" has decimal places eg. 10025.26584 will turn into 10k instead of NaN – Daniel Tonon Jul 10 '15 at 00:54
  • Its returning NaN in some cases..!! – Ritesh Jun 30 '16 at 11:27
  • abbreviateNumber(9999000) returns "10m" instead of "9.9m" – Rama Rao M Oct 04 '16 at 09:44
  • lacs is missing – Ravi verma Nov 20 '17 at 07:41
  • 2
    `shortNum` is not defined in the @PhilippLenssen's edit at the end `if (shortValue % 1 != 0) shortNum = shortValue.toFixed(1);` – Honza Nov 08 '18 at 16:08
  • This did not give me the results I was expecting. 200,000 should have rendered as 200K, not 0.2M. The answer below this seems more robust. – jamesmfriedman Jan 06 '20 at 22:42
  • @jamesmfriedman Did you read the question? This was the desired output by OP. – chucktator Mar 11 '20 at 15:15
  • This answer inspired this `const shortNumber = (num) => { var newnum = String(num); var app = null; var decimal = null; const suff = ["", "k", "m", "b", "t"]; for (let i = 0; i < suff.length; i++) { if (newnum.length > 3) { decimal = newnum[newnum.length - 3]; newnum = newnum.substring(0, newnum.length - 3); } else { app = i; break; } } return newnum + "." + (decimal ? "." + decimal : "") + suff[app]; };` onto which the op can just prefix a 0 if `if(shortNumber(.99).startsWith("."))` @jamesmfriedman – Nick Carducci for Carface Bank Aug 19 '21 at 15:10
  • It can't deal with rational numbers (eg. 24572752353.1) :( – Melroy van den Berg Nov 16 '21 at 22:30
  • How to return `200K` instead of `0.2M`? Should I use the other answer? – ozgrozer May 04 '22 at 14:21
  • I would add `if (Math.abs(value) >= 1000)` instead `if (value >= 1000)` to have support for negative values as well – lorandd May 29 '22 at 21:37
60

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
D.Deriso
  • 4,271
  • 2
  • 21
  • 14
33

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:

JBaczuk
  • 13,886
  • 10
  • 58
  • 86
James L.
  • 12,893
  • 4
  • 49
  • 60
19

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'
NuSkooler
  • 5,391
  • 1
  • 34
  • 58
13

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'));
HoangLong85
  • 287
  • 4
  • 2
7

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.

Community
  • 1
  • 1
ninjagecko
  • 88,546
  • 24
  • 137
  • 145
5

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')
})
danilowoz
  • 101
  • 1
  • 3
  • After trying every solution above in this thread, this is the only one that works correctly. Thanks Danilo! – ty. Apr 21 '19 at 18:17
4

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>');
Stefan Gabos
  • 1,345
  • 13
  • 15
1

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];
}
MichaelJones
  • 1,336
  • 2
  • 12
  • 22
  • I think this answer is great. I had a slightly different case where I didn't want to show values with leading zeros. I added if (adjustedValue.charAt(0) === '0') { return adjustedValue * 1000 + suffixes[suffixIndex - 1]; } else { return adjustedValue + suffixes[suffixIndex]; } – user3162553 Apr 27 '16 at 23:05
1

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)

Priyanshu Chauhan
  • 5,297
  • 5
  • 35
  • 34
1

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
Nimer Awad
  • 3,967
  • 3
  • 17
  • 31
1

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]}`;
};
Vixson
  • 589
  • 7
  • 8
1

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";
};
chethankumar
  • 409
  • 2
  • 5
  • 15
1

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]
}
mahshad
  • 23
  • 4
0
            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));

0

@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
Rishabh
  • 81
  • 1
  • 3
0

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";};
oooooo
  • 11
0

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

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;
}
Monwell Partee
  • 708
  • 7
  • 16