Search code examples
javascriptformattingnumber-formatting

Always display number with 3 digits and descriptor


Using JavaScript, I want to format a number to always display 3 digits, along with it's proper identifier (ex: Million, Thousand). If under 100,000, the number should only show the "thousands" digits

All numbers will be integers above zero, and the highest numbers will be in the trillions.

A few examples of what I'm looking for:

  • 1 Thousand
  • 13 Thousand
  • 627 Thousand
  • 2.85 Million
  • 67.9 Million
  • 153 Million
  • 9.52 Billion
  • etc...

All of the solutions I tried ended up becoming spaghetti code, and I am hoping someone can find a clean, smart solution.

I ended up using part of RobG's solution, but worked out the specifics on my own. I added rounding as well

function getNumberName(num) {
  var numNames = ['', 'Thousand', 'Million', 'Billion', 'Trillion'];
  num = num.toString();
  var len = num.length - 1;
  return numNames[len / 3 | 0];
}

function test(num) {
  var numStr = num.toString();
  if (num < 1000) {
    return numStr;
  } else if (num < 1000000) {
    return numStr.slice(0, -3) + "," + numStr.slice(-3);
  }
  numStr = Math.round(parseFloat(numStr.slice(0, 3) + "." + numStr[3])).toString() + Array(numStr.slice(3).length + 1).join("0");
  var remainder = numStr.length % 3;
  var before = numStr.slice(0, remainder);
  var after = numStr.slice(remainder, 3);
  var sep = "";
  if (before.length) {
    sep = ".";
  }
  return before + sep + after + " " + getNumberName(num);
}

var nums = [0, 1, 12, 123, 1234, 12345, 123456, 1237567, 12325678, 123856789, 123e7, 125e8, 123.6e9, 123e10];

nums.forEach(function(num) {
  document.write(num + ":  $" + test(num) + "<br/>");
});


Solution

  • For integers, you can try shortening the number to the required number of places, then adding a name, e.g.

    // For integers
    function getNumberName(num) {
      var numNames = ['','Thousand','Million','Billion'];
      var num = num.toString()
      var len = num.length - 1;
      var pow = numNames[len/3 | 0];
      return pow;
    }
    
    // For integers
    function abbreviateNumber(num, places) {
      places = places || 0;
      var len = num.toString().length - 1;
      var pow = len/3 | 0
      return (num < 1000? num : num/Math.pow(10, pow*3)).toFixed(places);
    }
    
    function getNumberAbbr(num, places) {
      return abbreviateNumber(num, places) + ' ' + getNumberName(num);
    }
    
    var nums = [0,1,12,123,1234,12345,123456,1234567,12345678,123456789,123e7]
    
    nums.forEach(function(num) {
      console.log(num + ' : ' + getNumberAbbr(num,1));
    });
    

    The above is not complete. There should be a limit applied so that beyond, say 1 trillion, it stops shortening the number.