-2

I want to shorten decimals for large numbers like 1.348526328757346254637e91 to 1.34e91 for my javascript game that handles very large numbers. How can i do this? Here is the code i want the system in

function addClicks(amount) {
 clicks = clicks + amount * multiplier;
 document.getElementById("clicks").innerHTML = clicks;
}
Igor
  • 60,821
  • 10
  • 100
  • 175
Plazl
  • 11
  • 3
  • 1
    those numbers are likely to loose a vast amount of precision in javascript – Daniel A. White Sep 13 '21 at 16:09
  • 1
    Did you try [Number.prototype.toExponential](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toExponential) and specify 2 digits? – Wyck Sep 13 '21 at 16:11
  • Why? What is your goal? What are you doing with the numbers? More details are needed. – Randy Casburn Sep 13 '21 at 16:19
  • @RandyCasburn, I thought that was the point...to _format_ the number as a string. There are bigger problems here anyway, like floating point precision. Maybe we should be suggesting BigInt. `innerHTML` is a string anyway. – Wyck Sep 13 '21 at 16:32
  • @Wyck - got it. You are on point here. – Randy Casburn Sep 13 '21 at 16:56

1 Answers1

0

This may be more of the solution you're looking for, if you like those clicker games. Also, this implementation explicitly does not round up, because it's no fun to be declared a centillionaire until you actually are one!

const americanNames = [
  'one', 'thousand', 'million', 'billion', 'trillion', 'quadrillion', 'quintillion', 'sextillion', 'septillion', 'octillion', 'nonillion',
  'decillion', 'undecillion', 'duodecillion', 'tredecillion', 'quattuordecillion', 'quindecillion', 'sexdecillion', 'septendecillion', 'octodecillion', 'novemdecillion', 
  'vigintillion', 'unvigintillion', 'duovigintillion', 'trevigintillion', 'quattuorvigintillion', 'quinvigintillion', 'sexvigintillion', 'septenvigintillion', 'octovigintillion', 'novemvigintillion',
  'trigintillion', 'untrigintillion', 'duotrigintillion', 'tretrigintillion', 'quattuortrigintillion', 'quintrigintillion', 'sextrigintillion', 'septentrigintillion', 'octotrigintillion', 'novemtrigintillion',
  'quadragintillion', 'unquadragintillion', 'duoquadragintillion', 'trequadragintillion', 'quattuorquadragintillion', 'quinquadragintillion', 'sexquadragintillion', 'septenquadragintillion', 'octoquadragintillion', 'novemquadragintillion',
  'quinquagintillion', 'unquinquagintillion', 'duoquinquagintillion', 'trequinquagintillion', 'quattuorquinquagintillion', 'quinquinquagintillion', 'sexquinquagintillion', 'septenquinquagintillion', 'octoquinquagintillion', 'novemquinquagintillion', 
  'sexagintillion', 'unsexagintillion', 'duosexagintillion', 'tresexagintillion', 'quattuorsexagintillion', 'quinsexagintillion', 'sexsexagintillion', 'septsexagintillion', 'octosexagintillion', 'novemsexagintillion',
  'septuagintillion', 'unseptuagintillion', 'duoseptuagintillion', 'treseptuagintillion', 'quattuorseptuagintillion', 'quinseptuagintillion', 'sexseptuagintillion', 'septseptuagintillion', 'octoseptuagintillion', 'novemseptuagintillion',
  'octogintillion', 'unoctogintillion', 'duooctogintillion', 'treoctogintillion', 'quattuoroctogintillion', 'quinoctogintillion', 'sexoctogintillion', 'septoctogintillion', 'octooctogintillion', 'novemoctogintillion',
  'nonagintillion', 'unnonagintillion', 'duononagintillion', 'trenonagintillion', 'quattuornonagintillion', 'quinnonagintillion', 'sexnonagintillion', 'septnonagintillion', 'octononagintillion', 'novemnonagintillion',
  'centillion',
  // Up to you past this point.
];

function formatBigPositiveNumber(n) {
  const str = BigInt(n).toString();
  const len = str.length;
  if (len <= 3) {
    return str;
  } else if (len <= 6) {
    return str.slice(0, len - 3) + ',' + str.slice(-3);
  } else {
    const magnitude = ((len - 1) / 3) | 0;
    const place = 1 + (len + 2) % 3;
    const sig = str.slice(0, 4);
    const name = americanNames[magnitude];
    if (!name) throw new Error('I cannot format that number');
    return sig.substring(0, place) + '.' + sig.substring(place) + ' ' + name
  }
}


//////// TEST CASES

const testCases = [
  [0, '0'],
  [1, '1'],
  [12, '12'],
  [123, '123'],
  [1234, '1,234'],
  [12345, '12,345'],
  [123456, '123,456'],
  [999999, '999,999'],
  [1234567, '1.234 million'],
  [12345678, '12.34 million'],
  [123456789, '123.4 million'],
  [1234567891, '1.234 billion'],
  [999999999, '999.9 million'], // Explicitly does not round up to billion on purpose!
  [1.348526328757346254637e91, '13.48 novemvigintillion'],
];

function fixedWidth(str, n) {
  return (' '.repeat(n) + str).slice(-n);
}

for (let [input, expected] of testCases) {
  const actual = formatBigPositiveNumber(input);
  console.log('\n%s\n%s', fixedWidth(input, 25), fixedWidth(expected, 25));
  console.log('%s', fixedWidth(actual, 25));
}
Wyck
  • 10,311
  • 6
  • 39
  • 60