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