Gets the name of a number, even if it's stupidly big. Supersedes TheoryOfNekomata/number-name.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 

100 Zeilen
2.4 KiB

  1. import BigNumber from 'bignumber.js';
  2. import {
  3. createBlankDigits,
  4. deconstructNumeric,
  5. groupDigits,
  6. NEGATIVE_SIGN,
  7. normalizeNumeric,
  8. Numeric,
  9. } from '../../../utils/numeric';
  10. import getLatinPowerName from '../../../utils/common/latinPowers';
  11. import {getGroupDigitsName} from '../../common/en';
  12. const config = {
  13. thousandName: 'thousand',
  14. thousandOrdinalName: 'thousandth',
  15. millia: 'millia',
  16. illion: 'illion',
  17. illionth: 'illionth',
  18. hundredsLatinNames: [
  19. '',
  20. 'cen',
  21. 'duocen',
  22. 'trecen',
  23. 'quadringen',
  24. 'quingen',
  25. 'sescen',
  26. 'septingen',
  27. 'octingen',
  28. 'nongen',
  29. ],
  30. onesLatinNames: ['', 'un', 'duo', 'tre', 'quattuor', 'quin', 'sex', 'septen', 'octo', 'novem'],
  31. tensLatinNames: [
  32. '',
  33. 'dec',
  34. 'vigin',
  35. 'trigin',
  36. 'quadragin',
  37. 'quinquagin',
  38. 'sexagin',
  39. 'septuagin',
  40. 'octogin',
  41. 'nonagin',
  42. ],
  43. onesSpecialLatinNames: ['', 'm', 'b', 'tr', 'quadr', 'quin', 'sex', 'sep', 'oct', 'non'],
  44. negative: 'negative',
  45. grouping: 3,
  46. };
  47. const getGroupIndexName = (index: BigNumber, ordinal: boolean) => {
  48. if (index.eq(1)) {
  49. return ordinal ? config.thousandOrdinalName : config.thousandName;
  50. }
  51. const basicIndex = index.minus(1);
  52. const isOdd = false;
  53. return getLatinPowerName(basicIndex, isOdd, ordinal, config);
  54. };
  55. const getGroupName = (g: [string, BigNumber], ordinal: boolean) => {
  56. const [digits, index] = g;
  57. if (index.lt(1)) {
  58. return getGroupDigitsName(digits, ordinal);
  59. }
  60. return [getGroupDigitsName(digits, false), getGroupIndexName(index, ordinal)].join(' ');
  61. };
  62. type Options = {
  63. groupSeparator: string,
  64. ordinal: boolean,
  65. }
  66. const getLocalizedNumberName = (xRaw: Numeric, options = {} as Partial<Options>) => {
  67. const {
  68. groupSeparator = ' ',
  69. ordinal = false,
  70. } = options;
  71. const x = normalizeNumeric(xRaw);
  72. const {significandDigits, exponent} = deconstructNumeric(x);
  73. const blankDigits = createBlankDigits(config.grouping);
  74. const groups = groupDigits(significandDigits, exponent, config.grouping);
  75. if (groups.length === 1) {
  76. return getGroupName(groups[0], ordinal);
  77. }
  78. const base = groups
  79. .filter(([digits]) => digits !== blankDigits)
  80. .map((g, i, gg) => getGroupName(g, ordinal ? i === gg.length - 1 : false))
  81. .join(groupSeparator);
  82. if (x.startsWith(NEGATIVE_SIGN)) {
  83. return [config.negative, base].join(' ');
  84. }
  85. return base;
  86. };
  87. export default getLocalizedNumberName;