Gets the name of a number, even if it's stupidly big. Supersedes TheoryOfNekomata/number-name.
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

131 строка
3.1 KiB

  1. /**
  2. * Group digits.
  3. */
  4. type GroupDigits = string;
  5. /**
  6. * Group place.
  7. */
  8. export type GroupPlace = bigint;
  9. /**
  10. * Group of digits and its place.
  11. *
  12. * The place refers to the order which the digits are grouped, e.g. for a number like
  13. *
  14. * 1,234,567
  15. *
  16. * The groups would be:
  17. *
  18. * ['001', 2]
  19. * ['234', 1]
  20. * ['567', 0]
  21. *
  22. * Note that groups do not necessarily have the same length of digits, such in the case of
  23. * South Asian numbering system:
  24. *
  25. * 1,00,00,000
  26. *
  27. * The groups would be:
  28. *
  29. * ['01', 3]
  30. * ['00', 2]
  31. * ['00', 1]
  32. * ['000', 0]
  33. */
  34. export type Group = [GroupDigits, GroupPlace];
  35. /**
  36. * Index of the group digits in a {@link Group|group}.
  37. */
  38. export const GROUP_DIGITS_INDEX = 0 as const;
  39. /**
  40. * Index of the group place in a {@link Group|group}.
  41. */
  42. export const GROUP_PLACE_INDEX = 1 as const;
  43. /**
  44. * System for stringifying and parsing numbers.
  45. */
  46. export interface NumberNameSystem {
  47. /**
  48. * Creates a negative string.
  49. * @param s - The string to make negative.
  50. * @returns string The negative string.
  51. */
  52. makeNegative: (s: string) => string;
  53. /**
  54. * Splits a string into groups.
  55. * @param value - The string to group.
  56. * @see {NumberNameSystem.combineGroups}
  57. * @returns Group[] The groups.
  58. */
  59. splitIntoGroups: (value: string) => Group[];
  60. /**
  61. * Creates a group string.
  62. * @param groups - The groups.
  63. * @param options - Options to use when creating the group.
  64. * @see {NumberNameSystem.parseGroups}
  65. * @returns string[] The groups represented into strings.
  66. */
  67. stringifyGroups: <T extends object>(groups: Group[], options?: T) => string[];
  68. /**
  69. * Merges tokens from stringified groups to a string.
  70. * @param tokens - The tokens to finalize.
  71. * @see {NumberNameSystem.tokenize}
  72. * @returns string The merged tokens.
  73. */
  74. mergeTokens: <T extends object>(tokens: string[], options?: T) => string;
  75. /**
  76. * Tokenizes a string.
  77. * @param value - The string to tokenize.
  78. * @see {NumberNameSystem.mergeTokens}
  79. * @returns string[] The tokens.
  80. */
  81. tokenize: (value: string) => string[];
  82. /**
  83. * Parses groups from a string.
  84. * @param tokens - The string to parse groups from.
  85. * @see {NumberNameSystem.stringifyGroups}
  86. * @returns Group[] The parsed groups.
  87. */
  88. parseGroups: (tokens: string[]) => Group[];
  89. /**
  90. * Combines groups into a string.
  91. * @param groups - The groups to combine.
  92. * @see {NumberNameSystem.splitIntoGroups}
  93. * @returns string The combined groups in exponential form.
  94. */
  95. combineGroups: (groups: Group[]) => string;
  96. }
  97. /**
  98. * Error thrown when an invalid token is encountered.
  99. */
  100. export class InvalidTokenError extends Error {
  101. constructor(token: string) {
  102. super(`Invalid token: ${token}`);
  103. }
  104. }
  105. export const bigIntMax = (...b: bigint[]) => b.reduce(
  106. (previousMax, current) => {
  107. if (typeof previousMax === 'undefined') {
  108. return current;
  109. }
  110. return previousMax > current ? previousMax : current;
  111. },
  112. undefined as bigint | undefined,
  113. );
  114. export const bigIntMin = (...b: bigint[]) => b.reduce(
  115. (previousMin, current) => {
  116. if (typeof previousMin === 'undefined') {
  117. return current;
  118. }
  119. return previousMin < current ? previousMin : current;
  120. },
  121. undefined as bigint | undefined,
  122. );