Get the name of a number, even if it's stupidly big.
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

53 lines
1.9 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. public convert = (value: string | number | bigint): string => {
  7. let converted: string[] = []
  8. const valueStr = value as string
  9. switch (typeof value!) {
  10. case 'string':
  11. // TODO bail out when exponent is too large!
  12. try {
  13. return this.convert(BigInt(new Big(valueStr).toFixed()))
  14. } catch (e) {}
  15. return this.convert(BigInt(valueStr))
  16. case 'number':
  17. return this.convert(BigInt(value as number))
  18. case 'bigint':
  19. let current = value as bigint
  20. let thousandPower = 0n
  21. while (current > 0n) {
  22. const hundreds = Number(((current % 1000n) / 100n) % 10n) as Digit
  23. const tens = Number(((current % 100n) / 10n) % 10n) as Digit
  24. const ones = Number(current % 10n) as Digit
  25. let kiloName: string | undefined
  26. let kiloCount: string
  27. if (!(ones === 0 && tens === 0 && hundreds === 0)) {
  28. if (thousandPower > 0n) {
  29. const { scale = 'short' } = this.options
  30. kiloName = this.system.getKiloName[scale!]!(thousandPower)
  31. }
  32. kiloCount = this.system.getKiloCount(hundreds, tens, ones)
  33. converted.unshift(this.system.joinKilo(kiloCount, kiloName))
  34. }
  35. thousandPower = thousandPower + 1n
  36. current = current / 1000n
  37. }
  38. return converted.join(' ')
  39. default:
  40. break
  41. }
  42. throw TypeError('Invalid argument passed to value.')
  43. }
  44. public readStream = (streamOptions: ReadStreamOptions): ConverterStream => {
  45. return new ConverterStream(this.convert, streamOptions)
  46. }
  47. }