Get the name of a number, even if it's stupidly big.
You can not select more than 25 topics 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.

47 lines
1.6 KiB

  1. import ConverterStream from './ConverterStream'
  2. import { ReadStreamOptions, ConvertOptions, NumberSystem, Digit } from './common'
  3. export default class Converter {
  4. constructor(private readonly system: NumberSystem) {}
  5. public convert = (value: string | number | bigint, options: ConvertOptions): string => {
  6. let converted: string[] = []
  7. switch (typeof value!) {
  8. case 'string':
  9. case 'number':
  10. return this.convert(BigInt(value), options)
  11. case 'bigint':
  12. let current = value as bigint
  13. let thousandPower = 0n
  14. while (current > 0n) {
  15. const hundreds = Number(((current % 1000n) / 100n) % 10n) as Digit
  16. const tens = Number(((current % 100n) / 10n) % 10n) as Digit
  17. const ones = Number(current % 10n) as Digit
  18. let kiloName: string | undefined
  19. let kiloCount: string
  20. if (!(ones === 0 && tens === 0 && hundreds === 0)) {
  21. if (thousandPower > 0n) {
  22. const { scale = 'short' } = options
  23. kiloName = this.system.getKiloName[scale!]!(thousandPower)
  24. }
  25. kiloCount = this.system.getKiloCount(hundreds, tens, ones)
  26. converted.unshift(this.system.joinKilo(kiloCount, kiloName))
  27. }
  28. thousandPower = thousandPower + 1n
  29. current = current / 1000n
  30. }
  31. return converted.join(' ')
  32. default:
  33. break
  34. }
  35. throw TypeError('Invalid argument passed to value.')
  36. }
  37. readStream(options: ReadStreamOptions): ConverterStream {
  38. const { scale = 'short', encoding = 'utf-8' } = options
  39. return new ConverterStream(this.system, { scale, encoding })
  40. }
  41. }