Gets the name of a number, even if it's stupidly big. Supersedes TheoryOfNekomata/number-name.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

113 rivejä
3.2 KiB

  1. import {BLANK_DIGIT, createBlankDigits, deconstructNumeric, Group, groupDigits, normalizeNumeric} from '../numeric';
  2. import BigNumber from 'bignumber.js';
  3. interface Config {
  4. hundredsLatinNames: string[],
  5. onesLatinNames: string[],
  6. onesSpecialLatinNames: string[],
  7. tensLatinNames: string[],
  8. illion: string,
  9. illionth: string,
  10. illiard?: string,
  11. illiardth?: string,
  12. millia: string,
  13. }
  14. const getLatinPowerGroupDigitsName = (latinRaw: string, special: boolean, config: Config) => {
  15. const digits = latinRaw.padStart(3, BLANK_DIGIT);
  16. const [hundreds, tens, ones] = digits.split('').map(s => Number(s));
  17. const names = [];
  18. if (hundreds > 0) {
  19. names.push(config.hundredsLatinNames[hundreds]);
  20. names.push(config.onesLatinNames[ones]);
  21. names.push(config.tensLatinNames[tens]);
  22. } else {
  23. if (tens > 0) {
  24. names.push(config.onesLatinNames[ones]);
  25. names.push(config.tensLatinNames[tens]);
  26. } else {
  27. if (special) {
  28. names.push(config.onesSpecialLatinNames[ones]);
  29. } else if (ones > 1) {
  30. names.push(config.onesLatinNames[ones]);
  31. }
  32. }
  33. }
  34. return names.join('');
  35. };
  36. const getLatinPowerSuffix = (latinRaw: string, isOdd: boolean, special: boolean, ordinal: boolean, config: Config) => {
  37. const digits = latinRaw.padStart(3, BLANK_DIGIT);
  38. const [hundreds, tens, ones] = digits.split('').map(s => Number(s));
  39. const suffix = isOdd ? (ordinal ? config.illiardth : config.illiard) : (ordinal ? config.illionth : config.illion);
  40. if (hundreds > 0) {
  41. if (tens !== 1) {
  42. return 't' + suffix;
  43. }
  44. return suffix;
  45. }
  46. if (tens > 0) {
  47. switch (tens) {
  48. case 1:
  49. return suffix;
  50. default:
  51. break;
  52. }
  53. return 't' + suffix;
  54. }
  55. switch (ones) {
  56. case 1:
  57. case 2:
  58. case 3:
  59. case 4:
  60. return special ? suffix : 't' + suffix;
  61. case 5:
  62. case 6:
  63. case 7:
  64. return 't' + suffix;
  65. case 8:
  66. case 9:
  67. return suffix;
  68. default:
  69. break;
  70. }
  71. return '';
  72. };
  73. const getLatinPowerGroupName = (g: Group, config: Config) => {
  74. const [digits, index] = g;
  75. if (index.lt(1)) {
  76. return getLatinPowerGroupDigitsName(digits, index.eq(0), config);
  77. }
  78. let milliaSuffix = '';
  79. for (let i = new BigNumber(0); i.lt(index); i = i.plus(1)) {
  80. milliaSuffix += config.millia;
  81. }
  82. return [getLatinPowerGroupDigitsName(digits, index.eq(0), config), milliaSuffix].join('');
  83. };
  84. const getLatinPowerName = (latinRaw: BigNumber, isOdd: boolean, ordinal: boolean, config: Config) => {
  85. const x = normalizeNumeric(latinRaw);
  86. const {significandDigits, exponent} = deconstructNumeric(x);
  87. const blankDigits = createBlankDigits(3);
  88. const groups = groupDigits(significandDigits, exponent, 3);
  89. if (groups.length === 1) {
  90. return [
  91. getLatinPowerGroupName(groups[0], config),
  92. getLatinPowerSuffix(groups[0][0], isOdd, true, ordinal, config),
  93. ].join('');
  94. }
  95. const visibleGroups = groups.filter(([digits]) => digits !== blankDigits);
  96. const [lastVisibleGroup] = visibleGroups.slice(-1);
  97. return [
  98. ...visibleGroups.map(g => getLatinPowerGroupName(g, config)),
  99. getLatinPowerSuffix(lastVisibleGroup[0], isOdd, lastVisibleGroup[1].eq(0), ordinal, config),
  100. ].join('');
  101. };
  102. export default getLatinPowerName;