Gets the name of a number, even if it's stupidly big. Supersedes TheoryOfNekomata/number-name.
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 

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