Get the name of a number, even if it's stupidly big.
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
Repozitorijs ir arhivēts. Tam var aplūkot failus un to var klonēt, bet nevar iesūtīt jaunas izmaiņas, kā arī atvērt jaunas problēmas/izmaiņu pieprasījumus.

100 rindas
3.3 KiB

  1. import Big from 'big.js'
  2. import ConverterStream from './ConverterStream'
  3. import { ReadStreamOptions, ConvertOptions, NumberSystem, Digit } from './common'
  4. export default class Converter {
  5. constructor(private readonly system: NumberSystem, private options: ConvertOptions) {}
  6. private convertString = (value: string): string => {
  7. let converted: string[] = []
  8. try {
  9. const big = new Big(value)
  10. const { e: exponent, c: coefficients } = big
  11. const isExponentSmall = exponent < 1000
  12. if (isExponentSmall) {
  13. return this.convert(BigInt(big.toFixed()))
  14. }
  15. let currentPlace = exponent % 3
  16. let thousandPower = BigInt(exponent) / 3n
  17. coefficients.reduce(
  18. ([place, hundredsRaw = 0, tensRaw = 0, onesRaw = 0], c) => {
  19. let thePlace = (place + 3) % 3
  20. const nextPlace = (place + 3 - 1) % 3
  21. switch (thePlace) {
  22. case 2:
  23. return [nextPlace, c, tensRaw, onesRaw]
  24. case 1:
  25. return [nextPlace, hundredsRaw, c, onesRaw]
  26. default:
  27. case 0:
  28. break
  29. }
  30. let kiloName: string | undefined
  31. let kiloCount: string
  32. const hundreds = hundredsRaw as Digit
  33. const tens = tensRaw as Digit
  34. const ones = c as Digit
  35. if (!(ones === 0 && tens === 0 && hundreds === 0)) {
  36. if (thousandPower > 0n) {
  37. const { scale = 'short' } = this.options
  38. kiloName = this.system.getKiloName[scale!]!(thousandPower)
  39. }
  40. kiloCount = this.system.getKiloCount(hundreds, tens, ones)
  41. converted.push(this.system.joinKilo(kiloCount, kiloName))
  42. }
  43. thousandPower = thousandPower - 1n
  44. return [nextPlace, 0, 0, 0]
  45. },
  46. [currentPlace],
  47. )
  48. } catch {}
  49. return converted.join(' ')
  50. }
  51. private convertBigInt = (value: bigint): string => {
  52. let converted: string[] = []
  53. let current = value as bigint
  54. let thousandPower = 0n
  55. while (current > 0n) {
  56. const hundreds = Number(((current % 1000n) / 100n) % 10n) as Digit
  57. const tens = Number(((current % 100n) / 10n) % 10n) as Digit
  58. const ones = Number(current % 10n) as Digit
  59. let kiloName: string | undefined
  60. let kiloCount: string
  61. if (!(ones === 0 && tens === 0 && hundreds === 0)) {
  62. if (thousandPower > 0n) {
  63. const { scale = 'short' } = this.options
  64. kiloName = this.system.getKiloName[scale!]!(thousandPower)
  65. }
  66. kiloCount = this.system.getKiloCount(hundreds, tens, ones)
  67. converted.unshift(this.system.joinKilo(kiloCount, kiloName))
  68. }
  69. thousandPower = thousandPower + 1n
  70. current = current / 1000n
  71. }
  72. return converted.join(' ')
  73. }
  74. public convert = (value: string | number | bigint): string => {
  75. switch (typeof value!) {
  76. case 'string':
  77. return this.convertString(value as string)
  78. case 'number':
  79. return this.convertString(value.toString(10))
  80. case 'bigint':
  81. return this.convertBigInt(value as bigint)
  82. default:
  83. break
  84. }
  85. throw TypeError('Invalid argument passed to value.')
  86. }
  87. public readStream = (streamOptions: ReadStreamOptions): ConverterStream => {
  88. return new ConverterStream(this.convert, streamOptions)
  89. }
  90. }