瀏覽代碼

Start decoupling core code to locales

Ensure all three sample locales are correct with consistent rules. Also expanded the number type of hundreds to bigint to anticipate extra large numbers.
master
TheoryOfNekomata 4 年之前
父節點
當前提交
a2ec5ea57c
共有 70 個檔案被更改,包括 1322 行新增1012 行删除
  1. +3
    -3
      package.json
  2. +19
    -16
      src/Converter.ts
  3. +6
    -7
      src/ConverterStream.ts
  4. +0
    -10
      src/NumberSystem.ts
  5. +0
    -14
      src/NumberSystemNameTable.ts
  6. +0
    -11
      src/common.ts
  7. +70
    -0
      src/common/index.ts
  8. +5
    -3
      src/systems/de/base/hundredTimes.ts
  9. +63
    -63
      src/systems/de/base/kilo/combiningPrefix.test.ts
  10. +34
    -23
      src/systems/de/base/kilo/combiningPrefix.ts
  11. +3
    -2
      src/systems/de/base/kilo/hundreds.ts
  12. +2
    -2
      src/systems/de/base/kilo/ones.test.ts
  13. +3
    -2
      src/systems/de/base/kilo/ones.ts
  14. +3
    -2
      src/systems/de/base/kilo/tens.ts
  15. +3
    -2
      src/systems/de/base/ones.ts
  16. +3
    -2
      src/systems/de/base/tenPlus.ts
  17. +3
    -2
      src/systems/de/base/tenTimes.ts
  18. +3
    -2
      src/systems/de/construct/tens.ts
  19. +129
    -0
      src/systems/de/getEuropeanLongKiloName.test.ts
  20. +23
    -0
      src/systems/de/getEuropeanLongKiloName.ts
  21. +18
    -0
      src/systems/de/getKiloCount.ts
  22. +0
    -129
      src/systems/de/getLongKiloName.test.ts
  23. +0
    -25
      src/systems/de/getLongKiloName.ts
  24. +14
    -0
      src/systems/de/index.ts
  25. +13
    -0
      src/systems/de/joinKilo.ts
  26. +0
    -92
      src/systems/de/names.json
  27. +19
    -0
      src/systems/de/names.ts
  28. +0
    -14
      src/systems/en.ts
  29. +3
    -2
      src/systems/en/base/hundredTimes.ts
  30. +63
    -63
      src/systems/en/base/kilo/combiningPrefix.test.ts
  31. +34
    -23
      src/systems/en/base/kilo/combiningPrefix.ts
  32. +3
    -2
      src/systems/en/base/kilo/hundreds.ts
  33. +2
    -2
      src/systems/en/base/kilo/ones.test.ts
  34. +3
    -2
      src/systems/en/base/kilo/ones.ts
  35. +3
    -2
      src/systems/en/base/kilo/tens.ts
  36. +3
    -2
      src/systems/en/base/ones.ts
  37. +3
    -2
      src/systems/en/base/tenPlus.ts
  38. +3
    -2
      src/systems/en/base/tenTimes.ts
  39. +2
    -1
      src/systems/en/construct/tens.ts
  40. +129
    -0
      src/systems/en/getEuropeanLongKiloName.test.ts
  41. +23
    -0
      src/systems/en/getEuropeanLongKiloName.ts
  42. +4
    -2
      src/systems/en/getKiloCount.ts
  43. +85
    -85
      src/systems/en/getLongKiloName.test.ts
  44. +8
    -8
      src/systems/en/getLongKiloName.ts
  45. +76
    -76
      src/systems/en/getShortKiloName.test.ts
  46. +8
    -8
      src/systems/en/getShortKiloName.ts
  47. +18
    -0
      src/systems/en/index.ts
  48. +5
    -0
      src/systems/en/joinKilo.ts
  49. +0
    -92
      src/systems/en/names.json
  50. +30
    -0
      src/systems/en/names.ts
  51. +4
    -3
      src/systems/tl/base/hundredTimes.ts
  52. +65
    -65
      src/systems/tl/base/kilo/combiningPrefix.test.ts
  53. +34
    -23
      src/systems/tl/base/kilo/combiningPrefix.ts
  54. +3
    -2
      src/systems/tl/base/kilo/hundreds.ts
  55. +2
    -2
      src/systems/tl/base/kilo/ones.test.ts
  56. +3
    -2
      src/systems/tl/base/kilo/ones.ts
  57. +3
    -2
      src/systems/tl/base/kilo/tens.ts
  58. +3
    -2
      src/systems/tl/base/ones.ts
  59. +4
    -3
      src/systems/tl/base/tenPlus.ts
  60. +3
    -2
      src/systems/tl/base/tenTimes.ts
  61. +3
    -2
      src/systems/tl/construct/tens.ts
  62. +9
    -9
      src/systems/tl/getKiloCount.test.ts
  63. +3
    -3
      src/systems/tl/getKiloCount.ts
  64. +120
    -0
      src/systems/tl/getShortKiloName.test.ts
  65. +20
    -0
      src/systems/tl/getShortKiloName.ts
  66. +14
    -0
      src/systems/tl/index.ts
  67. +18
    -0
      src/systems/tl/joinKilo.ts
  68. +0
    -92
      src/systems/tl/names.json
  69. +63
    -0
      src/systems/tl/names.ts
  70. +1
    -0
      tsconfig.json

+ 3
- 3
package.json 查看文件

@@ -1,4 +1,7 @@
{
"name": "@theoryofnekomata/number-name",
"author": "TheoryOfNekomata <allan.crisostomo@outlook.com> (https://modal.sh)",
"module": "dist/number-name.esm.js",
"version": "0.1.0",
"license": "MIT",
"main": "dist/index.js",
@@ -23,9 +26,6 @@
"pre-commit": "tsdx lint"
}
},
"name": "@theoryofnekomata/number-name",
"author": "TheoryOfNekomata <allan.crisostomo@outlook.com> (https://modal.sh)",
"module": "dist/number-name.esm.js",
"devDependencies": {
"@types/node": "^14.6.0",
"fast-check": "^2.1.0",


+ 19
- 16
src/Converter.ts 查看文件

@@ -1,33 +1,36 @@
import NumberSystem from './NumberSystem'
import ConverterStream from './ConverterStream'
import { ReadStreamOptions, ConvertOptions } from './common'
import { ReadStreamOptions, ConvertOptions, NumberSystem, Digit } from './common'

export default class Converter {
constructor(private readonly system: NumberSystem) {}

convert(value: string | number | bigint, options: ConvertOptions) {
public convert = (value: string | number | bigint, options: ConvertOptions): string => {
let converted: string[] = []
switch (typeof value!) {
case 'string':
return ''
case 'bigint':
case 'number':
let current = value as number
let thousandPower = 0
while (current > 0) {
const hundreds = Math.floor((current % 1000) / 100)
const tens = Math.floor((current % 100) / 10)
const ones = Math.floor(current % 10)
return this.convert(BigInt(value), options)
case 'bigint':
let current = value as bigint
let thousandPower = 0n
while (current > 0n) {
const hundreds = Number(((current % 1000n) / 100n) % 10n) as Digit
const tens = Number(((current % 100n) / 10n) % 10n) as Digit
const ones = Number(current % 10n) as Digit

let kiloName: string | undefined
let kiloCount: string
if (!(ones === 0 && tens === 0 && hundreds === 0)) {
if (thousandPower > 0) {
if (thousandPower > 0n) {
const { scale = 'short' } = options
converted.unshift(this.system.getKiloName[scale!]!(thousandPower))
kiloName = this.system.getKiloName[scale!]!(thousandPower)
}
converted.unshift(this.system.getKiloCount(hundreds, tens, ones))
kiloCount = this.system.getKiloCount(hundreds, tens, ones)
converted.unshift(this.system.joinKilo(kiloCount, kiloName))
}

thousandPower = thousandPower + 1
current = Math.floor(current / 1000)
thousandPower = thousandPower + 1n
current = current / 1000n
}
return converted.join(' ')
default:


+ 6
- 7
src/ConverterStream.ts 查看文件

@@ -1,16 +1,15 @@
import { Transform } from 'stream'
import NumberSystem from './NumberSystem'
import { ReadStreamOptions } from './common'
import { Digit, NumberSystem, ReadStreamOptions } from './common'

export default class ConverterStream extends Transform {
private thousandPower: number = 0
private thousandPower: bigint = 0n

constructor(private readonly system: NumberSystem, private readonly options: ReadStreamOptions) {
super()
this.thousandPower = 0
this.thousandPower = 0n
}

_transform(chunk: any, _encoding: BufferEncoding, callback: Function) {
_transform(chunk: Buffer, _encoding: BufferEncoding, callback: Function) {
const { scale, encoding } = this.options

const [ones = 0, tens = 0, hundreds = 0] = chunk
@@ -31,7 +30,7 @@ export default class ConverterStream extends Transform {
}
this.push(
this.system
.getKiloCount(hundreds, tens, ones)
.getKiloCount(hundreds as Digit, tens as Digit, ones as Digit)
.split('')
.reverse()
.join(''),
@@ -39,7 +38,7 @@ export default class ConverterStream extends Transform {
this.push(' ')
}

this.thousandPower = this.thousandPower + 1
this.thousandPower = this.thousandPower + 1n
callback()
}
}

+ 0
- 10
src/NumberSystem.ts 查看文件

@@ -1,10 +0,0 @@
export type GetKiloCount = (hundreds: number, tens: number, ones: number) => string
export type GetKiloName = (thousandPower: number) => string

export default interface NumberSystem {
getKiloCount: GetKiloCount
getKiloName: {
short?: GetKiloName
long?: GetKiloName
}
}

+ 0
- 14
src/NumberSystemNameTable.ts 查看文件

@@ -1,14 +0,0 @@
export default interface NumberSystemNameTable {
units: string[10]
tenPlus: string[10]
tenTimes: string[10]
hundred: string
thousand: string
kiloSpecialUnits: string[10]
kiloUnits: string[10]
kiloTens: string[10]
kiloHundreds: string[10]
kiloThousand: string
kiloEvenSuffix: string
kiloOddSuffix: string
}

+ 0
- 11
src/common.ts 查看文件

@@ -1,11 +0,0 @@
export type Scale = 'long' | 'short'

export interface ConvertOptions {
scale?: Scale
}

export interface StreamOptions {
encoding?: BufferEncoding
}

export type ReadStreamOptions = ConvertOptions & StreamOptions

+ 70
- 0
src/common/index.ts 查看文件

@@ -0,0 +1,70 @@
export type Scale = 'long' | 'short'

export interface ConvertOptions {
scale?: Scale
}

export interface StreamOptions {
encoding?: BufferEncoding
}

type NumberDigit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

type StringDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'

export type Digit = NumberDigit | StringDigit

export type ReadStreamOptions = ConvertOptions & StreamOptions

export type GetKiloCount = (hundreds: Digit, tens: Digit, ones: Digit) => string
export type GetKiloName = (thousandPower: bigint) => string
export type JoinKilo = (kiloCount: string, kiloName?: string) => string

export interface NumberSystem {
getKiloCount: GetKiloCount
getKiloName: {
short?: GetKiloName
long?: GetKiloName
europeanLong?: GetKiloName
}
joinKilo: JoinKilo
}

interface DigitString {
[0]: string
[1]: string
[2]: string
[3]: string
[4]: string
[5]: string
[6]: string
[7]: string
[8]: string
[9]: string
['0']: string
['1']: string
['2']: string
['3']: string
['4']: string
['5']: string
['6']: string
['7']: string
['8']: string
['9']: string
}

export interface NumberSystemNameTable {
units: DigitString
tenPlus: DigitString
tenTimes: DigitString
hundred: string
thousand: string
kiloSpecialUnits: DigitString
kiloUnits: DigitString
kiloTens: DigitString
kiloHundreds: DigitString
kiloThousand: string
kiloEvenSuffix: string
kiloOddSuffix: string
and: string
}

+ 5
- 3
src/systems/de/base/hundredTimes.ts 查看文件

@@ -1,7 +1,8 @@
import NAMES from '../names.json'
import { Digit } from '../../../common'
import NAMES from '../names'

interface HundredTimes {
(x100: number): string
(x100: Digit): string
}

/**
@@ -9,6 +10,7 @@ interface HundredTimes {
* @param {number} x100 - The number in the hundreds place.
* @returns {string} The name of the number in the hundreds place.
*/
const hundredTimes: HundredTimes = (x100) => (x100 === 0 ? NAMES.units[0] : [NAMES.units[x100], NAMES.hundred].join(''))
const hundredTimes: HundredTimes = (x100) =>
Number(x100) === 0 ? NAMES.units[0] : [NAMES.units[x100], NAMES.hundred].join('')

export default hundredTimes

+ 63
- 63
src/systems/de/base/kilo/combiningPrefix.test.ts 查看文件

@@ -8,8 +8,8 @@ it('should be a callable', () => {
expect(typeof combiningPrefix).toBe('function')
})

it('should accept 4 arguments', () => {
expect(combiningPrefix).toHaveLength(4)
it('should accept a minimum of 3 arguments', () => {
expect(combiningPrefix).toHaveLength(3)
})

describe('on 0 in hundreds place', () => {
@@ -26,7 +26,7 @@ describe('on 0 in hundreds place', () => {
${8} | ${'8'} | ${'octi'}
${9} | ${'9'} | ${'noni'}
`('should return "$name" on $display', ({ value, name }) => {
expect(combiningPrefix(0, 0, value)).toBe(name)
expect(combiningPrefix(0n, 0, value)).toBe(name)
})
})

@@ -55,22 +55,22 @@ describe('on 0 in hundreds place', () => {
${8} | ${'octo' + tensName}
${9} | ${'novem' + tensName}
`(`should return "$display" for ${tens}$ones`, ({ ones, display }) => {
expect(combiningPrefix(0, tens, ones)).toBe(display)
expect(combiningPrefix(0n, tens, ones)).toBe(display)
})
})
})

describe.each`
hundreds | hundredsName
${1} | ${'cen'}
${2} | ${'duocen'}
${3} | ${'trecen'}
${4} | ${'quadringen'}
${5} | ${'quingen'}
${6} | ${'sescen'}
${7} | ${'septingen'}
${8} | ${'octingen'}
${9} | ${'nongen'}
${1n} | ${'cen'}
${2n} | ${'duocen'}
${3n} | ${'trecen'}
${4n} | ${'quadringen'}
${5n} | ${'quingen'}
${6n} | ${'sescen'}
${7n} | ${'septingen'}
${8n} | ${'octingen'}
${9n} | ${'nongen'}
`('on $hundreds in hundreds place', ({ hundreds, hundredsName }) => {
describe.each`
tens | tensName
@@ -105,43 +105,43 @@ describe.each`

describe.each`
hundredThousands | hundredThousandsName
${1} | ${'cen'}
${2} | ${'duocen'}
${3} | ${'trecen'}
${4} | ${'quadringen'}
${5} | ${'quingen'}
${6} | ${'sescen'}
${7} | ${'septingen'}
${8} | ${'octingen'}
${9} | ${'nongen'}
${1n} | ${'cen'}
${2n} | ${'duocen'}
${3n} | ${'trecen'}
${4n} | ${'quadringen'}
${5n} | ${'quingen'}
${6n} | ${'sescen'}
${7n} | ${'septingen'}
${8n} | ${'octingen'}
${9n} | ${'nongen'}
`('on $hundredThousands in hundred thousands place', ({ hundredThousands, hundredThousandsName }) => {
describe.each`
tenThousands | tenThousandsName
${0} | ${''}
${1} | ${'dec'}
${2} | ${'vigin'}
${3} | ${'trigin'}
${4} | ${'quadragin'}
${5} | ${'quinquagin'}
${6} | ${'sexagin'}
${7} | ${'septuagin'}
${8} | ${'octogin'}
${9} | ${'nonagin'}
${0n} | ${''}
${1n} | ${'dec'}
${2n} | ${'vigin'}
${3n} | ${'trigin'}
${4n} | ${'quadragin'}
${5n} | ${'quinquagin'}
${6n} | ${'sexagin'}
${7n} | ${'septuagin'}
${8n} | ${'octogin'}
${9n} | ${'nonagin'}
`('on $tenThousands in ten thousands place', ({ tenThousands, tenThousandsName }) => {
test.each`
thousands | display | name
${0} | ${hundredThousands + '' + tenThousands + '0000'} | ${hundredThousandsName + tenThousandsName + 'milliati'}
${1000} | ${hundredThousands + '' + tenThousands + '1000'} | ${hundredThousandsName + 'un' + tenThousandsName + 'milliati'}
${2000} | ${hundredThousands + '' + tenThousands + '2000'} | ${hundredThousandsName + 'duo' + tenThousandsName + 'milliati'}
${3000} | ${hundredThousands + '' + tenThousands + '3000'} | ${hundredThousandsName + 'tre' + tenThousandsName + 'milliati'}
${4000} | ${hundredThousands + '' + tenThousands + '4000'} | ${hundredThousandsName + 'quattuor' + tenThousandsName + 'milliati'}
${5000} | ${hundredThousands + '' + tenThousands + '5000'} | ${hundredThousandsName + 'quin' + tenThousandsName + 'milliati'}
${6000} | ${hundredThousands + '' + tenThousands + '6000'} | ${hundredThousandsName + 'sex' + tenThousandsName + 'milliati'}
${7000} | ${hundredThousands + '' + tenThousands + '7000'} | ${hundredThousandsName + 'septen' + tenThousandsName + 'milliati'}
${8000} | ${hundredThousands + '' + tenThousands + '8000'} | ${hundredThousandsName + 'octo' + tenThousandsName + 'milliati'}
${9000} | ${hundredThousands + '' + tenThousands + '9000'} | ${hundredThousandsName + 'novem' + tenThousandsName + 'milliati'}
${0n} | ${hundredThousands + '' + tenThousands + '0000'} | ${hundredThousandsName + tenThousandsName + 'milliati'}
${1000n} | ${hundredThousands + '' + tenThousands + '1000'} | ${hundredThousandsName + 'un' + tenThousandsName + 'milliati'}
${2000n} | ${hundredThousands + '' + tenThousands + '2000'} | ${hundredThousandsName + 'duo' + tenThousandsName + 'milliati'}
${3000n} | ${hundredThousands + '' + tenThousands + '3000'} | ${hundredThousandsName + 'tre' + tenThousandsName + 'milliati'}
${4000n} | ${hundredThousands + '' + tenThousands + '4000'} | ${hundredThousandsName + 'quattuor' + tenThousandsName + 'milliati'}
${5000n} | ${hundredThousands + '' + tenThousands + '5000'} | ${hundredThousandsName + 'quin' + tenThousandsName + 'milliati'}
${6000n} | ${hundredThousands + '' + tenThousands + '6000'} | ${hundredThousandsName + 'sex' + tenThousandsName + 'milliati'}
${7000n} | ${hundredThousands + '' + tenThousands + '7000'} | ${hundredThousandsName + 'septen' + tenThousandsName + 'milliati'}
${8000n} | ${hundredThousands + '' + tenThousands + '8000'} | ${hundredThousandsName + 'octo' + tenThousandsName + 'milliati'}
${9000n} | ${hundredThousands + '' + tenThousands + '9000'} | ${hundredThousandsName + 'novem' + tenThousandsName + 'milliati'}
`(`should return "$name" for $display`, ({ thousands, name }) => {
const kiloHundreds = hundredThousands * 1000 + tenThousands * 100 + thousands / 100
const kiloHundreds = hundredThousands * 1000n + tenThousands * 100n + thousands / 100n
expect(combiningPrefix(kiloHundreds, 0, 0)).toBe(name)
})
})
@@ -149,30 +149,30 @@ describe.each`

test.each`
value | display | name
${1} | ${'1000000'} | ${'milliamilliati'}
${2} | ${'2000000'} | ${'duomilliamilliati'}
${3} | ${'3000000'} | ${'tremilliamilliati'}
${4} | ${'4000000'} | ${'quattuormilliamilliati'}
${5} | ${'5000000'} | ${'quinmilliamilliati'}
${6} | ${'6000000'} | ${'sexmilliamilliati'}
${7} | ${'7000000'} | ${'septenmilliamilliati'}
${8} | ${'8000000'} | ${'octomilliamilliati'}
${9} | ${'9000000'} | ${'novemmilliamilliati'}
${1n} | ${'1000000'} | ${'milliamilliati'}
${2n} | ${'2000000'} | ${'duomilliamilliati'}
${3n} | ${'3000000'} | ${'tremilliamilliati'}
${4n} | ${'4000000'} | ${'quattuormilliamilliati'}
${5n} | ${'5000000'} | ${'quinmilliamilliati'}
${6n} | ${'6000000'} | ${'sexmilliamilliati'}
${7n} | ${'7000000'} | ${'septenmilliamilliati'}
${8n} | ${'8000000'} | ${'octomilliamilliati'}
${9n} | ${'9000000'} | ${'novemmilliamilliati'}
`('should return "$name" on $display', ({ value, name }) => {
expect(combiningPrefix(value * 10000, 0, 0)).toBe(name)
expect(combiningPrefix(value * 10000n, 0, 0)).toBe(name)
})

test.each`
value | display | name
${1} | ${'1001000'} | ${'milliamilliaunmilliati'}
${2} | ${'2002000'} | ${'duomilliamilliaduomilliati'}
${3} | ${'3003000'} | ${'tremilliamilliatremilliati'}
${4} | ${'4004000'} | ${'quattuormilliamilliaquattuormilliati'}
${5} | ${'5005000'} | ${'quinmilliamilliaquinmilliati'}
${6} | ${'6006000'} | ${'sexmilliamilliasexmilliati'}
${7} | ${'7007000'} | ${'septenmilliamilliaseptenmilliati'}
${8} | ${'8008000'} | ${'octomilliamilliaoctomilliati'}
${9} | ${'9009000'} | ${'novemmilliamillianovemmilliati'}
${1n} | ${'1001000'} | ${'milliamilliaunmilliati'}
${2n} | ${'2002000'} | ${'duomilliamilliaduomilliati'}
${3n} | ${'3003000'} | ${'tremilliamilliatremilliati'}
${4n} | ${'4004000'} | ${'quattuormilliamilliaquattuormilliati'}
${5n} | ${'5005000'} | ${'quinmilliamilliaquinmilliati'}
${6n} | ${'6006000'} | ${'sexmilliamilliasexmilliati'}
${7n} | ${'7007000'} | ${'septenmilliamilliaseptenmilliati'}
${8n} | ${'8008000'} | ${'octomilliamilliaoctomilliati'}
${9n} | ${'9009000'} | ${'novemmilliamillianovemmilliati'}
`('should return "$name" on $display', ({ value, name }) => {
expect(combiningPrefix(value * 10010, 0, 0)).toBe(name)
expect(combiningPrefix(value * 10010n, 0, 0)).toBe(name)
})

+ 34
- 23
src/systems/de/base/kilo/combiningPrefix.ts 查看文件

@@ -1,63 +1,74 @@
import NAMES from '../../names.json'
import { Digit } from '../../../../common'
import NAMES from '../../names'
import ones from './ones'
import tens from './tens'
import hundreds from './hundreds'

interface CombiningPrefix {
(kiloHundreds: number, kiloTens: number, kiloOnes: number, kiloPower?: number): string
(kiloHundreds: bigint, kiloTens: Digit, kiloOnes: Digit, kiloPower?: bigint): string
}

const combiningPrefix: CombiningPrefix = (kiloHundredsRaw, kiloTens, kiloOnes, kiloPower = 0) => {
let kiloHundreds = kiloHundredsRaw
const combiningPrefix: CombiningPrefix = (kiloHundreds, kiloTens, kiloOnes, kiloPower = 0n) => {
let currentKiloHundreds = kiloHundreds
let prefix = ''

const isMillia = kiloHundredsRaw >= 10
const isMillia = kiloHundreds >= 10n
if (isMillia) {
prefix += combiningPrefix(
Math.floor(kiloHundredsRaw / 1000),
Math.floor((kiloHundredsRaw / 100) % 10),
Math.floor((kiloHundredsRaw / 10) % 10),
kiloPower + 1,
kiloHundreds / 1000n,
(Number(kiloHundreds / 100n) % 10) as Digit,
(Number(kiloHundreds / 10n) % 10) as Digit,
kiloPower + 1n,
)
kiloHundreds = kiloHundredsRaw % 10
currentKiloHundreds = kiloHundreds % 10n
}

const hasHundreds = kiloHundreds > 0
const hasHundreds = currentKiloHundreds > 0n
if (hasHundreds) {
prefix += hundreds(kiloHundreds)
prefix += hundreds(Number(currentKiloHundreds % 10n) as Digit)
}

const kiloTensNumber = Number(kiloTens)
const kiloOnesNumber = Number(kiloOnes)

if (
kiloPower > 0 &&
((kiloHundreds === 0 && kiloTens === 0 && kiloOnes > 1) ||
((kiloHundreds > 0 || kiloTens > 0) && kiloOnes > 0) ||
(kiloHundreds === 0 && kiloTens === 0 && kiloOnes === 1 && prefix.endsWith(NAMES.kiloThousand)))
((currentKiloHundreds === 0n && kiloTensNumber === 0 && kiloOnesNumber > 1) ||
((currentKiloHundreds > 0n || kiloTensNumber > 0) && kiloOnesNumber > 0) ||
(currentKiloHundreds === 0n &&
kiloTensNumber === 0 &&
kiloOnesNumber === 1 &&
prefix.endsWith(NAMES.kiloThousand)))
) {
// http://www.isthe.com/chongo/tech/math/number/howhigh.html
// Section: Titanic size numbers < 10^3000003
prefix += ones(kiloOnes, false)
}
if (kiloPower === 0 && kiloOnes > 0) {
const special = kiloHundreds === 0 && kiloTens === 0
if (kiloPower === 0n && kiloOnesNumber) {
const special = currentKiloHundreds === 0n && kiloTensNumber === 0
prefix += ones(kiloOnes, special)
if (special && [5, 6].includes(kiloOnes)) {
if (special && [5, 6].includes(Number(kiloOnes))) {
prefix += 't'
}
}
if (kiloTens > 0) {
if (kiloTensNumber > 0) {
prefix += tens(kiloTens)
}

if (kiloPower > 0) {
if (!(kiloHundreds === 0 && kiloTens === 0 && kiloOnes === 0)) {
for (let p = 0; p < kiloPower; p += 1) {
if (kiloPower > 0n) {
if (!(currentKiloHundreds === 0n && kiloTensNumber === 0 && kiloOnesNumber === 0)) {
for (let p = 0n; p < kiloPower; p += 1n) {
prefix += NAMES.kiloThousand
}
}
return prefix
}

if ((kiloHundreds === 0 && kiloTens > 1) || (kiloHundreds > 0 && kiloTens !== 1) || kiloHundredsRaw >= 10) {
if (
(currentKiloHundreds === 0n && kiloTensNumber > 1) ||
(currentKiloHundreds > 0n && kiloTensNumber !== 1) ||
kiloHundreds >= 10
) {
prefix += 't'
}
return prefix + 'i'


+ 3
- 2
src/systems/de/base/kilo/hundreds.ts 查看文件

@@ -1,7 +1,8 @@
import NAMES from '../../names.json'
import { Digit } from '../../../../common'
import NAMES from '../../names'

interface Hundreds {
(kiloHundreds: number): string
(kiloHundreds: Digit): string
}

const hundreds: Hundreds = (kiloHundreds) => NAMES.kiloHundreds[kiloHundreds]


+ 2
- 2
src/systems/de/base/kilo/ones.test.ts 查看文件

@@ -8,8 +8,8 @@ it('should be a callable', () => {
expect(typeof ones).toBe('function')
})

it('should accept 2 arguments', () => {
expect(ones).toHaveLength(2)
it('should accept a minimum of 1 argument', () => {
expect(ones).toHaveLength(1)
})

describe('on ordinary units', () => {


+ 3
- 2
src/systems/de/base/kilo/ones.ts 查看文件

@@ -1,7 +1,8 @@
import NAMES from '../../names.json'
import { Digit } from '../../../../common'
import NAMES from '../../names'

interface Ones {
(kiloOnes: number, special: boolean): string
(kiloOnes: Digit, special: boolean): string
}

const ones: Ones = (kiloOnes, special = false) =>


+ 3
- 2
src/systems/de/base/kilo/tens.ts 查看文件

@@ -1,7 +1,8 @@
import NAMES from '../../names.json'
import { Digit } from '../../../../common'
import NAMES from '../../names'

interface Tens {
(kiloTens: number): string
(kiloTens: Digit): string
}

const tens: Tens = (kiloTens) => NAMES.kiloTens[kiloTens]


+ 3
- 2
src/systems/de/base/ones.ts 查看文件

@@ -1,7 +1,8 @@
import NAMES from '../names.json'
import { Digit } from '../../../common'
import NAMES from '../names'

interface Ones {
(x1: number): string
(x1: Digit): string
}

/**


+ 3
- 2
src/systems/de/base/tenPlus.ts 查看文件

@@ -1,7 +1,8 @@
import NAMES from '../names.json'
import { Digit } from '../../../common'
import NAMES from '../names'

interface TenPlus {
(ones: number): string
(ones: Digit): string
}

/**


+ 3
- 2
src/systems/de/base/tenTimes.ts 查看文件

@@ -1,7 +1,8 @@
import NAMES from '../names.json'
import { Digit } from '../../../common'
import NAMES from '../names'

interface TenTimes {
(x10: number): string
(x10: Digit): string
}

/**


+ 3
- 2
src/systems/de/construct/tens.ts 查看文件

@@ -1,10 +1,11 @@
import NAMES from '../names.json'
import { Digit } from '../../../common'
import NAMES from '../names'
import ones from '../base/ones'
import tenPlus from '../base/tenPlus'
import getBaseTenTimesName from '../base/tenTimes'

interface Tens {
(x10: number, x1: number): string
(x10: Digit, x1: Digit): string
}

const tens: Tens = (x10, x1) => {


+ 129
- 0
src/systems/de/getEuropeanLongKiloName.test.ts 查看文件

@@ -0,0 +1,129 @@
import getEuropeanLongKiloName from './getEuropeanLongKiloName'

it('should exist', () => {
expect(getEuropeanLongKiloName).toBeDefined()
})

it('should be a callable', () => {
expect(typeof getEuropeanLongKiloName).toBe('function')
})

it('should accept 1 argument', () => {
expect(getEuropeanLongKiloName).toHaveLength(1)
})

test.each`
thousandPower | name
${0n} | ${''}
${1n} | ${'tausend'}
${2n} | ${'million'}
${3n} | ${'milliard'}
${4n} | ${'billion'}
${5n} | ${'billiard'}
${6n} | ${'trillion'}
${7n} | ${'trilliard'}
${8n} | ${'quadrillion'}
${9n} | ${'quadrilliard'}
${10n} | ${'quintillion'}
${11n} | ${'quintilliard'}
${12n} | ${'sextillion'}
${13n} | ${'sextilliard'}
${14n} | ${'septillion'}
${15n} | ${'septilliard'}
${16n} | ${'octillion'}
${17n} | ${'octilliard'}
${18n} | ${'nonillion'}
${19n} | ${'nonilliard'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getEuropeanLongKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${20n} | ${'decillion'}
${40n} | ${'vigintillion'}
${60n} | ${'trigintillion'}
${80n} | ${'quadragintillion'}
${100n} | ${'quinquagintillion'}
${120n} | ${'sexagintillion'}
${140n} | ${'septuagintillion'}
${160n} | ${'octogintillion'}
${180n} | ${'nonagintillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getEuropeanLongKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${200n} | ${'centillion'}
${400n} | ${'duocentillion'}
${600n} | ${'trecentillion'}
${800n} | ${'quadringentillion'}
${1000n} | ${'quingentillion'}
${1200n} | ${'sescentillion'}
${1400n} | ${'septingentillion'}
${1600n} | ${'octingentillion'}
${1800n} | ${'nongentillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getEuropeanLongKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${2000n} | ${'milliatillion'}
${4000n} | ${'duomilliatillion'}
${6000n} | ${'tremilliatillion'}
${8000n} | ${'quattuormilliatillion'}
${10000n} | ${'quinmilliatillion'}
${12000n} | ${'sexmilliatillion'}
${14000n} | ${'septenmilliatillion'}
${16000n} | ${'octomilliatillion'}
${18000n} | ${'novemmilliatillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getEuropeanLongKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${20000n} | ${'decmilliatillion'}
${40000n} | ${'viginmilliatillion'}
${60000n} | ${'triginmilliatillion'}
${80000n} | ${'quadraginmilliatillion'}
${100000n} | ${'quinquaginmilliatillion'}
${120000n} | ${'sexaginmilliatillion'}
${140000n} | ${'septuaginmilliatillion'}
${160000n} | ${'octoginmilliatillion'}
${180000n} | ${'nonaginmilliatillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getEuropeanLongKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${200000n} | ${'cenmilliatillion'}
${400000n} | ${'duocenmilliatillion'}
${600000n} | ${'trecenmilliatillion'}
${800000n} | ${'quadringenmilliatillion'}
${1000000n} | ${'quingenmilliatillion'}
${1200000n} | ${'sescenmilliatillion'}
${1400000n} | ${'septingenmilliatillion'}
${1600000n} | ${'octingenmilliatillion'}
${1800000n} | ${'nongenmilliatillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getEuropeanLongKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${2000000n} | ${'milliamilliatillion'}
${4000000n} | ${'duomilliamilliatillion'}
${6000000n} | ${'tremilliamilliatillion'}
${8000000n} | ${'quattuormilliamilliatillion'}
${10000000n} | ${'quinmilliamilliatillion'}
${12000000n} | ${'sexmilliamilliatillion'}
${14000000n} | ${'septenmilliamilliatillion'}
${16000000n} | ${'octomilliamilliatillion'}
${18000000n} | ${'novemmilliamilliatillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getEuropeanLongKiloName(thousandPower)).toBe(name)
})

+ 23
- 0
src/systems/de/getEuropeanLongKiloName.ts 查看文件

@@ -0,0 +1,23 @@
import { Digit, GetKiloName } from '../../common'
import NAMES from './names'
import getKiloCombiningPrefix from './base/kilo/combiningPrefix'

const getEuropeanLongKiloName: GetKiloName = (thousandPower) => {
if (thousandPower === 0n) {
return ''
}
if (thousandPower === 1n) {
return NAMES.thousand
}
const kilo = thousandPower
const kiloHundreds = kilo / 2n / 100n
const kiloTens = (Number(kilo / 2n / 10n) % 10) as Digit
const kiloOnes = (Number(kilo / 2n) % 10) as Digit
const kiloCombiningPrefix = getKiloCombiningPrefix(kiloHundreds, kiloTens, kiloOnes)

return thousandPower % 2n === 0n
? kiloCombiningPrefix + NAMES.kiloEvenSuffix
: kiloCombiningPrefix + NAMES.kiloOddSuffix
}

export default getEuropeanLongKiloName

+ 18
- 0
src/systems/de/getKiloCount.ts 查看文件

@@ -0,0 +1,18 @@
import { GetKiloCount, Digit } from '../../common'
import constructTens from './construct/tens'
import hundredTimes from './base/hundredTimes'

const getKiloCount: GetKiloCount = (x100Raw, x10, x1) => {
const x100 = Number(BigInt(x100Raw) % 10n) as Digit
if (x100 < 1) {
return constructTens(x10, x1)
}

if (x10 === 0 && x1 === 0) {
return hundredTimes(x100)
}

return [hundredTimes(x100), constructTens(x10, x1)].join('')
}

export default getKiloCount

+ 0
- 129
src/systems/de/getLongKiloName.test.ts 查看文件

@@ -1,129 +0,0 @@
import getKiloName from './getLongKiloName'

it('should exist', () => {
expect(getKiloName).toBeDefined()
})

it('should be a callable', () => {
expect(typeof getKiloName).toBe('function')
})

it('should accept 1 argument', () => {
expect(getKiloName).toHaveLength(1)
})

test.each`
thousandPower | name
${0} | ${''}
${1} | ${'Tausend'}
${2} | ${'Million'}
${3} | ${'Milliard'}
${4} | ${'Billion'}
${5} | ${'Billiard'}
${6} | ${'Trillion'}
${7} | ${'Trilliard'}
${8} | ${'Quadrillion'}
${9} | ${'Quadrilliard'}
${10} | ${'Quintillion'}
${11} | ${'Quintilliard'}
${12} | ${'Sextillion'}
${13} | ${'Sextilliard'}
${14} | ${'Septillion'}
${15} | ${'Septilliard'}
${16} | ${'Octillion'}
${17} | ${'Octilliard'}
${18} | ${'Nonillion'}
${19} | ${'Nonilliard'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${20} | ${'Decillion'}
${40} | ${'Vigintillion'}
${60} | ${'Trigintillion'}
${80} | ${'Quadragintillion'}
${100} | ${'Quinquagintillion'}
${120} | ${'Sexagintillion'}
${140} | ${'Septuagintillion'}
${160} | ${'Octogintillion'}
${180} | ${'Nonagintillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${200} | ${'Centillion'}
${400} | ${'Duocentillion'}
${600} | ${'Trecentillion'}
${800} | ${'Quadringentillion'}
${1000} | ${'Quingentillion'}
${1200} | ${'Sescentillion'}
${1400} | ${'Septingentillion'}
${1600} | ${'Octingentillion'}
${1800} | ${'Nongentillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${2000} | ${'Milliatillion'}
${4000} | ${'Duomilliatillion'}
${6000} | ${'Tremilliatillion'}
${8000} | ${'Quattuormilliatillion'}
${10000} | ${'Quinmilliatillion'}
${12000} | ${'Sexmilliatillion'}
${14000} | ${'Septenmilliatillion'}
${16000} | ${'Octomilliatillion'}
${18000} | ${'Novemmilliatillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${20000} | ${'Decmilliatillion'}
${40000} | ${'Viginmilliatillion'}
${60000} | ${'Triginmilliatillion'}
${80000} | ${'Quadraginmilliatillion'}
${100000} | ${'Quinquaginmilliatillion'}
${120000} | ${'Sexaginmilliatillion'}
${140000} | ${'Septuaginmilliatillion'}
${160000} | ${'Octoginmilliatillion'}
${180000} | ${'Nonaginmilliatillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${200000} | ${'Cenmilliatillion'}
${400000} | ${'Duocenmilliatillion'}
${600000} | ${'Trecenmilliatillion'}
${800000} | ${'Quadringenmilliatillion'}
${1000000} | ${'Quingenmilliatillion'}
${1200000} | ${'Sescenmilliatillion'}
${1400000} | ${'Septingenmilliatillion'}
${1600000} | ${'Octingenmilliatillion'}
${1800000} | ${'Nongenmilliatillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${2000000} | ${'Milliamilliatillion'}
${4000000} | ${'Duomilliamilliatillion'}
${6000000} | ${'Tremilliamilliatillion'}
${8000000} | ${'Quattuormilliamilliatillion'}
${10000000} | ${'Quinmilliamilliatillion'}
${12000000} | ${'Sexmilliamilliatillion'}
${14000000} | ${'Septenmilliamilliatillion'}
${16000000} | ${'Octomilliamilliatillion'}
${18000000} | ${'Novemmilliamilliatillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getKiloName(thousandPower)).toBe(name)
})

+ 0
- 25
src/systems/de/getLongKiloName.ts 查看文件

@@ -1,25 +0,0 @@
import { GetKiloName } from '../../NumberSystem'
import NAMES from './names.json'
import getKiloCombiningPrefix from './base/kilo/combiningPrefix'

const capitalizeFirstLetter = (word: string) => word.slice(0, 1).toUpperCase() + word.slice(1)

const getLongKiloName: GetKiloName = (thousandPower) => {
if (thousandPower === 0) {
return ''
}
if (thousandPower === 1) {
return capitalizeFirstLetter(NAMES.thousand)
}
const kilo = thousandPower
const kiloHundreds = Math.floor(kilo / 2 / 100)
const kiloTens = Math.floor((kilo / 2 / 10) % 10)
const kiloOnes = Math.floor((kilo / 2) % 10)
const kiloCombiningPrefix = getKiloCombiningPrefix(kiloHundreds, kiloTens, kiloOnes)

return capitalizeFirstLetter(
thousandPower % 2 === 0 ? kiloCombiningPrefix + NAMES.kiloEvenSuffix : kiloCombiningPrefix + NAMES.kiloOddSuffix,
)
}

export default getLongKiloName

+ 14
- 0
src/systems/de/index.ts 查看文件

@@ -0,0 +1,14 @@
import { NumberSystem } from '../../common'
import getKiloCount from './getKiloCount'
import getEuropeanLongKiloName from './getEuropeanLongKiloName'
import joinKilo from './joinKilo'

const numberSystem: NumberSystem = {
getKiloCount,
getKiloName: {
europeanLong: getEuropeanLongKiloName,
},
joinKilo,
}

export default numberSystem

+ 13
- 0
src/systems/de/joinKilo.ts 查看文件

@@ -0,0 +1,13 @@
import { JoinKilo } from '../../common'

const joinKilo: JoinKilo = (kiloCount, kiloName) =>
kiloName
? [
kiloCount,
' ',
kiloName.slice(0, 1).toUpperCase(), // capitalize kilo name
kiloName.slice(1),
].join('')
: kiloCount

export default joinKilo

+ 0
- 92
src/systems/de/names.json 查看文件

@@ -1,92 +0,0 @@
{
"units": [
"zero",
"ein",
"zwei",
"drei",
"vier",
"fünf",
"sechs",
"sieben",
"acht",
"neun"
],
"tenPlus": [
"zehn",
"elf",
"zwölf",
"dreizehn",
"vierzehn",
"fünfzehn",
"sechzehn",
"siebzehn",
"achtzehn",
"neunzehn"
],
"tenTimes": [
"zero",
"zehn",
"zwanzig",
"dreißig",
"vierzig",
"fünfzig",
"sechzig",
"siebzig",
"achtzig",
"neunzig"
],
"hundred": "hundert",
"thousand": "tausend",
"kiloSpecialUnits": [
"",
"m",
"b",
"tr",
"quadr",
"quin",
"sex",
"sept",
"oct",
"non"
],
"kiloUnits": [
"",
"un",
"duo",
"tre",
"quattuor",
"quin",
"sex",
"septen",
"octo",
"novem"
],
"kiloTens": [
"",
"dec",
"vigin",
"trigin",
"quadragin",
"quinquagin",
"sexagin",
"septuagin",
"octogin",
"nonagin"
],
"kiloHundreds": [
"",
"cen",
"duocen",
"trecen",
"quadringen",
"quingen",
"sescen",
"septingen",
"octingen",
"nongen"
],
"kiloThousand": "millia",
"kiloEvenSuffix": "llion",
"kiloOddSuffix": "lliard",
"and": "und"
}

+ 19
- 0
src/systems/de/names.ts 查看文件

@@ -0,0 +1,19 @@
import { NumberSystemNameTable } from '../../common'

const names: NumberSystemNameTable = {
units: ['zero', 'ein', 'zwei', 'drei', 'vier', 'fünf', 'sechs', 'sieben', 'acht', 'neun'],
tenPlus: ['zehn', 'elf', 'zwölf', 'dreizehn', 'vierzehn', 'fünfzehn', 'sechzehn', 'siebzehn', 'achtzehn', 'neunzehn'],
tenTimes: ['zero', 'zehn', 'zwanzig', 'dreißig', 'vierzig', 'fünfzig', 'sechzig', 'siebzig', 'achtzig', 'neunzig'],
hundred: 'hundert',
thousand: 'tausend',
kiloSpecialUnits: ['', 'm', 'b', 'tr', 'quadr', 'quin', 'sex', 'sept', 'oct', 'non'],
kiloUnits: ['', 'un', 'duo', 'tre', 'quattuor', 'quin', 'sex', 'septen', 'octo', 'novem'],
kiloTens: ['', 'dec', 'vigin', 'trigin', 'quadragin', 'quinquagin', 'sexagin', 'septuagin', 'octogin', 'nonagin'],
kiloHundreds: ['', 'cen', 'duocen', 'trecen', 'quadringen', 'quingen', 'sescen', 'septingen', 'octingen', 'nongen'],
kiloThousand: 'millia',
kiloEvenSuffix: 'llion',
kiloOddSuffix: 'lliard',
and: 'und',
}

export default names

+ 0
- 14
src/systems/en.ts 查看文件

@@ -1,14 +0,0 @@
import NumberSystem from '../NumberSystem'
import getKiloCount from './en/getKiloCount'
import getLongKiloName from './en/getLongKiloName'
import getShortKiloName from './en/getShortKiloName'

const en: NumberSystem = {
getKiloCount,
getKiloName: {
short: getShortKiloName,
long: getLongKiloName,
},
}

export default en

+ 3
- 2
src/systems/en/base/hundredTimes.ts 查看文件

@@ -1,7 +1,8 @@
import NAMES from '../names.json'
import { Digit } from '../../../common'
import NAMES from '../names'

interface HundredTimes {
(x100: number): string
(x100: Digit): string
}

/**


+ 63
- 63
src/systems/en/base/kilo/combiningPrefix.test.ts 查看文件

@@ -8,8 +8,8 @@ it('should be a callable', () => {
expect(typeof combiningPrefix).toBe('function')
})

it('should accept 4 arguments', () => {
expect(combiningPrefix).toHaveLength(4)
it('should accept a minimum of 3 arguments', () => {
expect(combiningPrefix).toHaveLength(3)
})

describe('on 0 in hundreds place', () => {
@@ -26,7 +26,7 @@ describe('on 0 in hundreds place', () => {
${8} | ${'8'} | ${'octi'}
${9} | ${'9'} | ${'noni'}
`('should return "$name" on $display', ({ value, name }) => {
expect(combiningPrefix(0, 0, value)).toBe(name)
expect(combiningPrefix(0n, 0, value)).toBe(name)
})
})

@@ -55,22 +55,22 @@ describe('on 0 in hundreds place', () => {
${8} | ${'octo' + tensName}
${9} | ${'novem' + tensName}
`(`should return "$display" for ${tens}$ones`, ({ ones, display }) => {
expect(combiningPrefix(0, tens, ones)).toBe(display)
expect(combiningPrefix(0n, tens, ones)).toBe(display)
})
})
})

describe.each`
hundreds | hundredsName
${1} | ${'cen'}
${2} | ${'duocen'}
${3} | ${'trecen'}
${4} | ${'quadringen'}
${5} | ${'quingen'}
${6} | ${'sescen'}
${7} | ${'septingen'}
${8} | ${'octingen'}
${9} | ${'nongen'}
${1n} | ${'cen'}
${2n} | ${'duocen'}
${3n} | ${'trecen'}
${4n} | ${'quadringen'}
${5n} | ${'quingen'}
${6n} | ${'sescen'}
${7n} | ${'septingen'}
${8n} | ${'octingen'}
${9n} | ${'nongen'}
`('on $hundreds in hundreds place', ({ hundreds, hundredsName }) => {
describe.each`
tens | tensName
@@ -105,43 +105,43 @@ describe.each`

describe.each`
hundredThousands | hundredThousandsName
${1} | ${'cen'}
${2} | ${'duocen'}
${3} | ${'trecen'}
${4} | ${'quadringen'}
${5} | ${'quingen'}
${6} | ${'sescen'}
${7} | ${'septingen'}
${8} | ${'octingen'}
${9} | ${'nongen'}
${1n} | ${'cen'}
${2n} | ${'duocen'}
${3n} | ${'trecen'}
${4n} | ${'quadringen'}
${5n} | ${'quingen'}
${6n} | ${'sescen'}
${7n} | ${'septingen'}
${8n} | ${'octingen'}
${9n} | ${'nongen'}
`('on $hundredThousands in hundred thousands place', ({ hundredThousands, hundredThousandsName }) => {
describe.each`
tenThousands | tenThousandsName
${0} | ${''}
${1} | ${'dec'}
${2} | ${'vigin'}
${3} | ${'trigin'}
${4} | ${'quadragin'}
${5} | ${'quinquagin'}
${6} | ${'sexagin'}
${7} | ${'septuagin'}
${8} | ${'octogin'}
${9} | ${'nonagin'}
${0n} | ${''}
${1n} | ${'dec'}
${2n} | ${'vigin'}
${3n} | ${'trigin'}
${4n} | ${'quadragin'}
${5n} | ${'quinquagin'}
${6n} | ${'sexagin'}
${7n} | ${'septuagin'}
${8n} | ${'octogin'}
${9n} | ${'nonagin'}
`('on $tenThousands in ten thousands place', ({ tenThousands, tenThousandsName }) => {
test.each`
thousands | display | name
${0} | ${hundredThousands + '' + tenThousands + '0000'} | ${hundredThousandsName + tenThousandsName + 'milliati'}
${1000} | ${hundredThousands + '' + tenThousands + '1000'} | ${hundredThousandsName + 'un' + tenThousandsName + 'milliati'}
${2000} | ${hundredThousands + '' + tenThousands + '2000'} | ${hundredThousandsName + 'duo' + tenThousandsName + 'milliati'}
${3000} | ${hundredThousands + '' + tenThousands + '3000'} | ${hundredThousandsName + 'tre' + tenThousandsName + 'milliati'}
${4000} | ${hundredThousands + '' + tenThousands + '4000'} | ${hundredThousandsName + 'quattuor' + tenThousandsName + 'milliati'}
${5000} | ${hundredThousands + '' + tenThousands + '5000'} | ${hundredThousandsName + 'quin' + tenThousandsName + 'milliati'}
${6000} | ${hundredThousands + '' + tenThousands + '6000'} | ${hundredThousandsName + 'sex' + tenThousandsName + 'milliati'}
${7000} | ${hundredThousands + '' + tenThousands + '7000'} | ${hundredThousandsName + 'septen' + tenThousandsName + 'milliati'}
${8000} | ${hundredThousands + '' + tenThousands + '8000'} | ${hundredThousandsName + 'octo' + tenThousandsName + 'milliati'}
${9000} | ${hundredThousands + '' + tenThousands + '9000'} | ${hundredThousandsName + 'novem' + tenThousandsName + 'milliati'}
${0n} | ${hundredThousands + '' + tenThousands + '0000'} | ${hundredThousandsName + tenThousandsName + 'milliati'}
${1000n} | ${hundredThousands + '' + tenThousands + '1000'} | ${hundredThousandsName + 'un' + tenThousandsName + 'milliati'}
${2000n} | ${hundredThousands + '' + tenThousands + '2000'} | ${hundredThousandsName + 'duo' + tenThousandsName + 'milliati'}
${3000n} | ${hundredThousands + '' + tenThousands + '3000'} | ${hundredThousandsName + 'tre' + tenThousandsName + 'milliati'}
${4000n} | ${hundredThousands + '' + tenThousands + '4000'} | ${hundredThousandsName + 'quattuor' + tenThousandsName + 'milliati'}
${5000n} | ${hundredThousands + '' + tenThousands + '5000'} | ${hundredThousandsName + 'quin' + tenThousandsName + 'milliati'}
${6000n} | ${hundredThousands + '' + tenThousands + '6000'} | ${hundredThousandsName + 'sex' + tenThousandsName + 'milliati'}
${7000n} | ${hundredThousands + '' + tenThousands + '7000'} | ${hundredThousandsName + 'septen' + tenThousandsName + 'milliati'}
${8000n} | ${hundredThousands + '' + tenThousands + '8000'} | ${hundredThousandsName + 'octo' + tenThousandsName + 'milliati'}
${9000n} | ${hundredThousands + '' + tenThousands + '9000'} | ${hundredThousandsName + 'novem' + tenThousandsName + 'milliati'}
`(`should return "$name" for $display`, ({ thousands, name }) => {
const kiloHundreds = hundredThousands * 1000 + tenThousands * 100 + thousands / 100
const kiloHundreds = hundredThousands * 1000n + tenThousands * 100n + thousands / 100n
expect(combiningPrefix(kiloHundreds, 0, 0)).toBe(name)
})
})
@@ -149,30 +149,30 @@ describe.each`

test.each`
value | display | name
${1} | ${'1000000'} | ${'milliamilliati'}
${2} | ${'2000000'} | ${'duomilliamilliati'}
${3} | ${'3000000'} | ${'tremilliamilliati'}
${4} | ${'4000000'} | ${'quattuormilliamilliati'}
${5} | ${'5000000'} | ${'quinmilliamilliati'}
${6} | ${'6000000'} | ${'sexmilliamilliati'}
${7} | ${'7000000'} | ${'septenmilliamilliati'}
${8} | ${'8000000'} | ${'octomilliamilliati'}
${9} | ${'9000000'} | ${'novemmilliamilliati'}
${1n} | ${'1000000'} | ${'milliamilliati'}
${2n} | ${'2000000'} | ${'duomilliamilliati'}
${3n} | ${'3000000'} | ${'tremilliamilliati'}
${4n} | ${'4000000'} | ${'quattuormilliamilliati'}
${5n} | ${'5000000'} | ${'quinmilliamilliati'}
${6n} | ${'6000000'} | ${'sexmilliamilliati'}
${7n} | ${'7000000'} | ${'septenmilliamilliati'}
${8n} | ${'8000000'} | ${'octomilliamilliati'}
${9n} | ${'9000000'} | ${'novemmilliamilliati'}
`('should return "$name" on $display', ({ value, name }) => {
expect(combiningPrefix(value * 10000, 0, 0)).toBe(name)
expect(combiningPrefix(value * 10000n, 0, 0)).toBe(name)
})

test.each`
value | display | name
${1} | ${'1001000'} | ${'milliamilliaunmilliati'}
${2} | ${'2002000'} | ${'duomilliamilliaduomilliati'}
${3} | ${'3003000'} | ${'tremilliamilliatremilliati'}
${4} | ${'4004000'} | ${'quattuormilliamilliaquattuormilliati'}
${5} | ${'5005000'} | ${'quinmilliamilliaquinmilliati'}
${6} | ${'6006000'} | ${'sexmilliamilliasexmilliati'}
${7} | ${'7007000'} | ${'septenmilliamilliaseptenmilliati'}
${8} | ${'8008000'} | ${'octomilliamilliaoctomilliati'}
${9} | ${'9009000'} | ${'novemmilliamillianovemmilliati'}
${1n} | ${'1001000'} | ${'milliamilliaunmilliati'}
${2n} | ${'2002000'} | ${'duomilliamilliaduomilliati'}
${3n} | ${'3003000'} | ${'tremilliamilliatremilliati'}
${4n} | ${'4004000'} | ${'quattuormilliamilliaquattuormilliati'}
${5n} | ${'5005000'} | ${'quinmilliamilliaquinmilliati'}
${6n} | ${'6006000'} | ${'sexmilliamilliasexmilliati'}
${7n} | ${'7007000'} | ${'septenmilliamilliaseptenmilliati'}
${8n} | ${'8008000'} | ${'octomilliamilliaoctomilliati'}
${9n} | ${'9009000'} | ${'novemmilliamillianovemmilliati'}
`('should return "$name" on $display', ({ value, name }) => {
expect(combiningPrefix(value * 10010, 0, 0)).toBe(name)
expect(combiningPrefix(value * 10010n, 0, 0)).toBe(name)
})

+ 34
- 23
src/systems/en/base/kilo/combiningPrefix.ts 查看文件

@@ -1,63 +1,74 @@
import NAMES from '../../names.json'
import { Digit } from '../../../../common'
import NAMES from '../../names'
import ones from './ones'
import tens from './tens'
import hundreds from './hundreds'

interface CombiningPrefix {
(kiloHundreds: number, kiloTens: number, kiloOnes: number, kiloPower?: number): string
(kiloHundreds: bigint, kiloTens: Digit, kiloOnes: Digit, kiloPower?: bigint): string
}

const combiningPrefix: CombiningPrefix = (kiloHundredsRaw, kiloTens, kiloOnes, kiloPower = 0) => {
let kiloHundreds = kiloHundredsRaw
const combiningPrefix: CombiningPrefix = (kiloHundreds, kiloTens, kiloOnes, kiloPower = 0n) => {
let currentKiloHundreds = kiloHundreds
let prefix = ''

const isMillia = kiloHundredsRaw >= 10
const isMillia = kiloHundreds >= 10n
if (isMillia) {
prefix += combiningPrefix(
Math.floor(kiloHundredsRaw / 1000),
Math.floor((kiloHundredsRaw / 100) % 10),
Math.floor((kiloHundredsRaw / 10) % 10),
kiloPower + 1,
kiloHundreds / 1000n,
(Number(kiloHundreds / 100n) % 10) as Digit,
(Number(kiloHundreds / 10n) % 10) as Digit,
kiloPower + 1n,
)
kiloHundreds = kiloHundredsRaw % 10
currentKiloHundreds = kiloHundreds % 10n
}

const hasHundreds = kiloHundreds > 0
const hasHundreds = currentKiloHundreds > 0n
if (hasHundreds) {
prefix += hundreds(kiloHundreds)
prefix += hundreds(Number(currentKiloHundreds % 10n) as Digit)
}

const kiloTensNumber = Number(kiloTens)
const kiloOnesNumber = Number(kiloOnes)

if (
kiloPower > 0 &&
((kiloHundreds === 0 && kiloTens === 0 && kiloOnes > 1) ||
((kiloHundreds > 0 || kiloTens > 0) && kiloOnes > 0) ||
(kiloHundreds === 0 && kiloTens === 0 && kiloOnes === 1 && prefix.endsWith(NAMES.kiloThousand)))
((currentKiloHundreds === 0n && kiloTensNumber === 0 && kiloOnesNumber > 1) ||
((currentKiloHundreds > 0n || kiloTensNumber > 0) && kiloOnesNumber > 0) ||
(currentKiloHundreds === 0n &&
kiloTensNumber === 0 &&
kiloOnesNumber === 1 &&
prefix.endsWith(NAMES.kiloThousand)))
) {
// http://www.isthe.com/chongo/tech/math/number/howhigh.html
// Section: Titanic size numbers < 10^3000003
prefix += ones(kiloOnes, false)
}
if (kiloPower === 0 && kiloOnes > 0) {
const special = kiloHundreds === 0 && kiloTens === 0
if (kiloPower === 0n && kiloOnesNumber) {
const special = currentKiloHundreds === 0n && kiloTensNumber === 0
prefix += ones(kiloOnes, special)
if (special && [5, 6].includes(kiloOnes)) {
if (special && [5, 6].includes(Number(kiloOnes))) {
prefix += 't'
}
}
if (kiloTens > 0) {
if (kiloTensNumber > 0) {
prefix += tens(kiloTens)
}

if (kiloPower > 0) {
if (!(kiloHundreds === 0 && kiloTens === 0 && kiloOnes === 0)) {
for (let p = 0; p < kiloPower; p += 1) {
if (kiloPower > 0n) {
if (!(currentKiloHundreds === 0n && kiloTensNumber === 0 && kiloOnesNumber === 0)) {
for (let p = 0n; p < kiloPower; p += 1n) {
prefix += NAMES.kiloThousand
}
}
return prefix
}

if ((kiloHundreds === 0 && kiloTens > 1) || (kiloHundreds > 0 && kiloTens !== 1) || kiloHundredsRaw >= 10) {
if (
(currentKiloHundreds === 0n && kiloTensNumber > 1) ||
(currentKiloHundreds > 0n && kiloTensNumber !== 1) ||
kiloHundreds >= 10
) {
prefix += 't'
}
return prefix + 'i'


+ 3
- 2
src/systems/en/base/kilo/hundreds.ts 查看文件

@@ -1,7 +1,8 @@
import NAMES from '../../names.json'
import { Digit } from '../../../../common'
import NAMES from '../../names'

interface Hundreds {
(kiloHundreds: number): string
(kiloHundreds: Digit): string
}

const hundreds: Hundreds = (kiloHundreds) => NAMES.kiloHundreds[kiloHundreds]


+ 2
- 2
src/systems/en/base/kilo/ones.test.ts 查看文件

@@ -8,8 +8,8 @@ it('should be a callable', () => {
expect(typeof ones).toBe('function')
})

it('should accept 2 arguments', () => {
expect(ones).toHaveLength(2)
it('should accept a minimum of 1 argument', () => {
expect(ones).toHaveLength(1)
})

describe('on ordinary units', () => {


+ 3
- 2
src/systems/en/base/kilo/ones.ts 查看文件

@@ -1,7 +1,8 @@
import NAMES from '../../names.json'
import { Digit } from '../../../../common'
import NAMES from '../../names'

interface Ones {
(kiloOnes: number, special: boolean): string
(kiloOnes: Digit, special: boolean): string
}

const ones: Ones = (kiloOnes, special = false) =>


+ 3
- 2
src/systems/en/base/kilo/tens.ts 查看文件

@@ -1,7 +1,8 @@
import NAMES from '../../names.json'
import { Digit } from '../../../../common'
import NAMES from '../../names'

interface Tens {
(kiloTens: number): string
(kiloTens: Digit): string
}

const tens: Tens = (kiloTens) => NAMES.kiloTens[kiloTens]


+ 3
- 2
src/systems/en/base/ones.ts 查看文件

@@ -1,7 +1,8 @@
import NAMES from '../names.json'
import { Digit } from '../../../common'
import NAMES from '../names'

interface Ones {
(x1: number): string
(x1: Digit): string
}

/**


+ 3
- 2
src/systems/en/base/tenPlus.ts 查看文件

@@ -1,7 +1,8 @@
import NAMES from '../names.json'
import { Digit } from '../../../common'
import NAMES from '../names'

interface TenPlus {
(ones: number): string
(ones: Digit): string
}

/**


+ 3
- 2
src/systems/en/base/tenTimes.ts 查看文件

@@ -1,7 +1,8 @@
import NAMES from '../names.json'
import { Digit } from '../../../common'
import NAMES from '../names'

interface TenTimes {
(x10: number): string
(x10: Digit): string
}

/**


+ 2
- 1
src/systems/en/construct/tens.ts 查看文件

@@ -1,9 +1,10 @@
import { Digit } from '../../../common'
import ones from '../base/ones'
import tenPlus from '../base/tenPlus'
import getBaseTenTimesName from '../base/tenTimes'

interface Tens {
(x10: number, x1: number): string
(x10: Digit, x1: Digit): string
}

const tens: Tens = (x10, x1) => {


+ 129
- 0
src/systems/en/getEuropeanLongKiloName.test.ts 查看文件

@@ -0,0 +1,129 @@
import getEuropeanLongKiloName from './getEuropeanLongKiloName'

it('should exist', () => {
expect(getEuropeanLongKiloName).toBeDefined()
})

it('should be a callable', () => {
expect(typeof getEuropeanLongKiloName).toBe('function')
})

it('should accept 1 argument', () => {
expect(getEuropeanLongKiloName).toHaveLength(1)
})

test.each`
thousandPower | name
${0n} | ${''}
${1n} | ${'thousand'}
${2n} | ${'million'}
${3n} | ${'milliard'}
${4n} | ${'billion'}
${5n} | ${'billiard'}
${6n} | ${'trillion'}
${7n} | ${'trilliard'}
${8n} | ${'quadrillion'}
${9n} | ${'quadrilliard'}
${10n} | ${'quintillion'}
${11n} | ${'quintilliard'}
${12n} | ${'sextillion'}
${13n} | ${'sextilliard'}
${14n} | ${'septillion'}
${15n} | ${'septilliard'}
${16n} | ${'octillion'}
${17n} | ${'octilliard'}
${18n} | ${'nonillion'}
${19n} | ${'nonilliard'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getEuropeanLongKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${20n} | ${'decillion'}
${40n} | ${'vigintillion'}
${60n} | ${'trigintillion'}
${80n} | ${'quadragintillion'}
${100n} | ${'quinquagintillion'}
${120n} | ${'sexagintillion'}
${140n} | ${'septuagintillion'}
${160n} | ${'octogintillion'}
${180n} | ${'nonagintillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getEuropeanLongKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${200n} | ${'centillion'}
${400n} | ${'duocentillion'}
${600n} | ${'trecentillion'}
${800n} | ${'quadringentillion'}
${1000n} | ${'quingentillion'}
${1200n} | ${'sescentillion'}
${1400n} | ${'septingentillion'}
${1600n} | ${'octingentillion'}
${1800n} | ${'nongentillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getEuropeanLongKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${2000n} | ${'milliatillion'}
${4000n} | ${'duomilliatillion'}
${6000n} | ${'tremilliatillion'}
${8000n} | ${'quattuormilliatillion'}
${10000n} | ${'quinmilliatillion'}
${12000n} | ${'sexmilliatillion'}
${14000n} | ${'septenmilliatillion'}
${16000n} | ${'octomilliatillion'}
${18000n} | ${'novemmilliatillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getEuropeanLongKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${20000n} | ${'decmilliatillion'}
${40000n} | ${'viginmilliatillion'}
${60000n} | ${'triginmilliatillion'}
${80000n} | ${'quadraginmilliatillion'}
${100000n} | ${'quinquaginmilliatillion'}
${120000n} | ${'sexaginmilliatillion'}
${140000n} | ${'septuaginmilliatillion'}
${160000n} | ${'octoginmilliatillion'}
${180000n} | ${'nonaginmilliatillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getEuropeanLongKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${200000n} | ${'cenmilliatillion'}
${400000n} | ${'duocenmilliatillion'}
${600000n} | ${'trecenmilliatillion'}
${800000n} | ${'quadringenmilliatillion'}
${1000000n} | ${'quingenmilliatillion'}
${1200000n} | ${'sescenmilliatillion'}
${1400000n} | ${'septingenmilliatillion'}
${1600000n} | ${'octingenmilliatillion'}
${1800000n} | ${'nongenmilliatillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getEuropeanLongKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${2000000n} | ${'milliamilliatillion'}
${4000000n} | ${'duomilliamilliatillion'}
${6000000n} | ${'tremilliamilliatillion'}
${8000000n} | ${'quattuormilliamilliatillion'}
${10000000n} | ${'quinmilliamilliatillion'}
${12000000n} | ${'sexmilliamilliatillion'}
${14000000n} | ${'septenmilliamilliatillion'}
${16000000n} | ${'octomilliamilliatillion'}
${18000000n} | ${'novemmilliamilliatillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getEuropeanLongKiloName(thousandPower)).toBe(name)
})

+ 23
- 0
src/systems/en/getEuropeanLongKiloName.ts 查看文件

@@ -0,0 +1,23 @@
import { Digit, GetKiloName } from '../../common'
import NAMES from './names'
import getKiloCombiningPrefix from './base/kilo/combiningPrefix'

const getEuropeanLongKiloName: GetKiloName = (thousandPower) => {
if (thousandPower === 0n) {
return ''
}
if (thousandPower === 1n) {
return NAMES.thousand
}
const kilo = thousandPower
const kiloHundreds = kilo / 2n / 100n
const kiloTens = (Number(kilo / 2n / 10n) % 10) as Digit
const kiloOnes = (Number(kilo / 2n) % 10) as Digit
const kiloCombiningPrefix = getKiloCombiningPrefix(kiloHundreds, kiloTens, kiloOnes)

return thousandPower % 2n === 0n
? kiloCombiningPrefix + NAMES.kiloEvenSuffix
: kiloCombiningPrefix + NAMES.kiloOddSuffix
}

export default getEuropeanLongKiloName

+ 4
- 2
src/systems/en/getKiloCount.ts 查看文件

@@ -1,8 +1,9 @@
import { GetKiloCount } from '../../NumberSystem'
import { GetKiloCount, Digit } from '../../common'
import constructTens from './construct/tens'
import hundredTimes from './base/hundredTimes'

const getKiloCount: GetKiloCount = (x100, x10, x1) => {
const getKiloCount: GetKiloCount = (x100Raw, x10, x1) => {
const x100 = Number(BigInt(x100Raw) % 10n) as Digit
if (x100 < 1) {
return constructTens(x10, x1)
}
@@ -10,6 +11,7 @@ const getKiloCount: GetKiloCount = (x100, x10, x1) => {
if (x10 === 0 && x1 === 0) {
return hundredTimes(x100)
}

return [hundredTimes(x100), constructTens(x10, x1)].join(' ')
}



+ 85
- 85
src/systems/en/getLongKiloName.test.ts 查看文件

@@ -1,129 +1,129 @@
import getKiloName from './getLongKiloName'
import getLongKiloName from './getLongKiloName'

it('should exist', () => {
expect(getKiloName).toBeDefined()
expect(getLongKiloName).toBeDefined()
})

it('should be a callable', () => {
expect(typeof getKiloName).toBe('function')
expect(typeof getLongKiloName).toBe('function')
})

it('should accept 1 argument', () => {
expect(getKiloName).toHaveLength(1)
expect(getLongKiloName).toHaveLength(1)
})

test.each`
thousandPower | name
${0} | ${''}
${1} | ${'thousand'}
${2} | ${'million'}
${3} | ${'thousand million'}
${4} | ${'billion'}
${5} | ${'thousand billion'}
${6} | ${'trillion'}
${7} | ${'thousand trillion'}
${8} | ${'quadrillion'}
${9} | ${'thousand quadrillion'}
${10} | ${'quintillion'}
${11} | ${'thousand quintillion'}
${12} | ${'sextillion'}
${13} | ${'thousand sextillion'}
${14} | ${'septillion'}
${15} | ${'thousand septillion'}
${16} | ${'octillion'}
${17} | ${'thousand octillion'}
${18} | ${'nonillion'}
${19} | ${'thousand nonillion'}
${0n} | ${''}
${1n} | ${'thousand'}
${2n} | ${'million'}
${3n} | ${'thousand million'}
${4n} | ${'billion'}
${5n} | ${'thousand billion'}
${6n} | ${'trillion'}
${7n} | ${'thousand trillion'}
${8n} | ${'quadrillion'}
${9n} | ${'thousand quadrillion'}
${10n} | ${'quintillion'}
${11n} | ${'thousand quintillion'}
${12n} | ${'sextillion'}
${13n} | ${'thousand sextillion'}
${14n} | ${'septillion'}
${15n} | ${'thousand septillion'}
${16n} | ${'octillion'}
${17n} | ${'thousand octillion'}
${18n} | ${'nonillion'}
${19n} | ${'thousand nonillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getKiloName(thousandPower)).toBe(name)
expect(getLongKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${20} | ${'decillion'}
${40} | ${'vigintillion'}
${60} | ${'trigintillion'}
${80} | ${'quadragintillion'}
${100} | ${'quinquagintillion'}
${120} | ${'sexagintillion'}
${140} | ${'septuagintillion'}
${160} | ${'octogintillion'}
${180} | ${'nonagintillion'}
${20n} | ${'decillion'}
${40n} | ${'vigintillion'}
${60n} | ${'trigintillion'}
${80n} | ${'quadragintillion'}
${100n} | ${'quinquagintillion'}
${120n} | ${'sexagintillion'}
${140n} | ${'septuagintillion'}
${160n} | ${'octogintillion'}
${180n} | ${'nonagintillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getKiloName(thousandPower)).toBe(name)
expect(getLongKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${200} | ${'centillion'}
${400} | ${'duocentillion'}
${600} | ${'trecentillion'}
${800} | ${'quadringentillion'}
${1000} | ${'quingentillion'}
${1200} | ${'sescentillion'}
${1400} | ${'septingentillion'}
${1600} | ${'octingentillion'}
${1800} | ${'nongentillion'}
${200n} | ${'centillion'}
${400n} | ${'duocentillion'}
${600n} | ${'trecentillion'}
${800n} | ${'quadringentillion'}
${1000n} | ${'quingentillion'}
${1200n} | ${'sescentillion'}
${1400n} | ${'septingentillion'}
${1600n} | ${'octingentillion'}
${1800n} | ${'nongentillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getKiloName(thousandPower)).toBe(name)
expect(getLongKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${2000} | ${'milliatillion'}
${4000} | ${'duomilliatillion'}
${6000} | ${'tremilliatillion'}
${8000} | ${'quattuormilliatillion'}
${10000} | ${'quinmilliatillion'}
${12000} | ${'sexmilliatillion'}
${14000} | ${'septenmilliatillion'}
${16000} | ${'octomilliatillion'}
${18000} | ${'novemmilliatillion'}
${2000n} | ${'milliatillion'}
${4000n} | ${'duomilliatillion'}
${6000n} | ${'tremilliatillion'}
${8000n} | ${'quattuormilliatillion'}
${10000n} | ${'quinmilliatillion'}
${12000n} | ${'sexmilliatillion'}
${14000n} | ${'septenmilliatillion'}
${16000n} | ${'octomilliatillion'}
${18000n} | ${'novemmilliatillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getKiloName(thousandPower)).toBe(name)
expect(getLongKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${20000} | ${'decmilliatillion'}
${40000} | ${'viginmilliatillion'}
${60000} | ${'triginmilliatillion'}
${80000} | ${'quadraginmilliatillion'}
${100000} | ${'quinquaginmilliatillion'}
${120000} | ${'sexaginmilliatillion'}
${140000} | ${'septuaginmilliatillion'}
${160000} | ${'octoginmilliatillion'}
${180000} | ${'nonaginmilliatillion'}
${20000n} | ${'decmilliatillion'}
${40000n} | ${'viginmilliatillion'}
${60000n} | ${'triginmilliatillion'}
${80000n} | ${'quadraginmilliatillion'}
${100000n} | ${'quinquaginmilliatillion'}
${120000n} | ${'sexaginmilliatillion'}
${140000n} | ${'septuaginmilliatillion'}
${160000n} | ${'octoginmilliatillion'}
${180000n} | ${'nonaginmilliatillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getKiloName(thousandPower)).toBe(name)
expect(getLongKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${200000} | ${'cenmilliatillion'}
${400000} | ${'duocenmilliatillion'}
${600000} | ${'trecenmilliatillion'}
${800000} | ${'quadringenmilliatillion'}
${1000000} | ${'quingenmilliatillion'}
${1200000} | ${'sescenmilliatillion'}
${1400000} | ${'septingenmilliatillion'}
${1600000} | ${'octingenmilliatillion'}
${1800000} | ${'nongenmilliatillion'}
${200000n} | ${'cenmilliatillion'}
${400000n} | ${'duocenmilliatillion'}
${600000n} | ${'trecenmilliatillion'}
${800000n} | ${'quadringenmilliatillion'}
${1000000n} | ${'quingenmilliatillion'}
${1200000n} | ${'sescenmilliatillion'}
${1400000n} | ${'septingenmilliatillion'}
${1600000n} | ${'octingenmilliatillion'}
${1800000n} | ${'nongenmilliatillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getKiloName(thousandPower)).toBe(name)
expect(getLongKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${2000000} | ${'milliamilliatillion'}
${4000000} | ${'duomilliamilliatillion'}
${6000000} | ${'tremilliamilliatillion'}
${8000000} | ${'quattuormilliamilliatillion'}
${10000000} | ${'quinmilliamilliatillion'}
${12000000} | ${'sexmilliamilliatillion'}
${14000000} | ${'septenmilliamilliatillion'}
${16000000} | ${'octomilliamilliatillion'}
${18000000} | ${'novemmilliamilliatillion'}
${2000000n} | ${'milliamilliatillion'}
${4000000n} | ${'duomilliamilliatillion'}
${6000000n} | ${'tremilliamilliatillion'}
${8000000n} | ${'quattuormilliamilliatillion'}
${10000000n} | ${'quinmilliamilliatillion'}
${12000000n} | ${'sexmilliamilliatillion'}
${14000000n} | ${'septenmilliamilliatillion'}
${16000000n} | ${'octomilliamilliatillion'}
${18000000n} | ${'novemmilliamilliatillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getKiloName(thousandPower)).toBe(name)
expect(getLongKiloName(thousandPower)).toBe(name)
})

+ 8
- 8
src/systems/en/getLongKiloName.ts 查看文件

@@ -1,21 +1,21 @@
import { GetKiloName } from '../../NumberSystem'
import NAMES from './names.json'
import { Digit, GetKiloName } from '../../common'
import NAMES from './names'
import getKiloCombiningPrefix from './base/kilo/combiningPrefix'

const getLongKiloName: GetKiloName = (thousandPower) => {
if (thousandPower === 0) {
if (thousandPower === 0n) {
return ''
}
if (thousandPower === 1) {
if (thousandPower === 1n) {
return NAMES.thousand
}
const kilo = thousandPower
const kiloHundreds = Math.floor(kilo / 2 / 100)
const kiloTens = Math.floor((kilo / 2 / 10) % 10)
const kiloOnes = Math.floor((kilo / 2) % 10)
const kiloHundreds = kilo / 2n / 100n
const kiloTens = (Number(kilo / 2n / 10n) % 10) as Digit
const kiloOnes = (Number(kilo / 2n) % 10) as Digit
const baseKiloName = getKiloCombiningPrefix(kiloHundreds, kiloTens, kiloOnes) + NAMES.kiloEvenSuffix

return thousandPower % 2 === 0 ? baseKiloName : NAMES.thousand + ' ' + baseKiloName
return thousandPower % 2n === 0n ? baseKiloName : NAMES.thousand + ' ' + baseKiloName
}

export default getLongKiloName

+ 76
- 76
src/systems/en/getShortKiloName.test.ts 查看文件

@@ -1,120 +1,120 @@
import getKiloName from './getShortKiloName'
import getShortKiloName from './getShortKiloName'

it('should exist', () => {
expect(getKiloName).toBeDefined()
expect(getShortKiloName).toBeDefined()
})

it('should be a callable', () => {
expect(typeof getKiloName).toBe('function')
expect(typeof getShortKiloName).toBe('function')
})

it('should accept 1 argument', () => {
expect(getKiloName).toHaveLength(1)
expect(getShortKiloName).toHaveLength(1)
})

test.each`
thousandPower | name
${0} | ${''}
${1} | ${'thousand'}
${2} | ${'million'}
${3} | ${'billion'}
${4} | ${'trillion'}
${5} | ${'quadrillion'}
${6} | ${'quintillion'}
${7} | ${'sextillion'}
${8} | ${'septillion'}
${9} | ${'octillion'}
${10} | ${'nonillion'}
${0n} | ${''}
${1n} | ${'thousand'}
${2n} | ${'million'}
${3n} | ${'billion'}
${4n} | ${'trillion'}
${5n} | ${'quadrillion'}
${6n} | ${'quintillion'}
${7n} | ${'sextillion'}
${8n} | ${'septillion'}
${9n} | ${'octillion'}
${10n} | ${'nonillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getKiloName(thousandPower)).toBe(name)
expect(getShortKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${11} | ${'decillion'}
${21} | ${'vigintillion'}
${31} | ${'trigintillion'}
${41} | ${'quadragintillion'}
${51} | ${'quinquagintillion'}
${61} | ${'sexagintillion'}
${71} | ${'septuagintillion'}
${81} | ${'octogintillion'}
${91} | ${'nonagintillion'}
${11n} | ${'decillion'}
${21n} | ${'vigintillion'}
${31n} | ${'trigintillion'}
${41n} | ${'quadragintillion'}
${51n} | ${'quinquagintillion'}
${61n} | ${'sexagintillion'}
${71n} | ${'septuagintillion'}
${81n} | ${'octogintillion'}
${91n} | ${'nonagintillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getKiloName(thousandPower)).toBe(name)
expect(getShortKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${101} | ${'centillion'}
${201} | ${'duocentillion'}
${301} | ${'trecentillion'}
${401} | ${'quadringentillion'}
${501} | ${'quingentillion'}
${601} | ${'sescentillion'}
${701} | ${'septingentillion'}
${801} | ${'octingentillion'}
${901} | ${'nongentillion'}
${101n} | ${'centillion'}
${201n} | ${'duocentillion'}
${301n} | ${'trecentillion'}
${401n} | ${'quadringentillion'}
${501n} | ${'quingentillion'}
${601n} | ${'sescentillion'}
${701n} | ${'septingentillion'}
${801n} | ${'octingentillion'}
${901n} | ${'nongentillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getKiloName(thousandPower)).toBe(name)
expect(getShortKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${1001} | ${'milliatillion'}
${2001} | ${'duomilliatillion'}
${3001} | ${'tremilliatillion'}
${4001} | ${'quattuormilliatillion'}
${5001} | ${'quinmilliatillion'}
${6001} | ${'sexmilliatillion'}
${7001} | ${'septenmilliatillion'}
${8001} | ${'octomilliatillion'}
${9001} | ${'novemmilliatillion'}
${1001n} | ${'milliatillion'}
${2001n} | ${'duomilliatillion'}
${3001n} | ${'tremilliatillion'}
${4001n} | ${'quattuormilliatillion'}
${5001n} | ${'quinmilliatillion'}
${6001n} | ${'sexmilliatillion'}
${7001n} | ${'septenmilliatillion'}
${8001n} | ${'octomilliatillion'}
${9001n} | ${'novemmilliatillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getKiloName(thousandPower)).toBe(name)
expect(getShortKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${10001} | ${'decmilliatillion'}
${20001} | ${'viginmilliatillion'}
${30001} | ${'triginmilliatillion'}
${40001} | ${'quadraginmilliatillion'}
${50001} | ${'quinquaginmilliatillion'}
${60001} | ${'sexaginmilliatillion'}
${70001} | ${'septuaginmilliatillion'}
${80001} | ${'octoginmilliatillion'}
${90001} | ${'nonaginmilliatillion'}
${10001n} | ${'decmilliatillion'}
${20001n} | ${'viginmilliatillion'}
${30001n} | ${'triginmilliatillion'}
${40001n} | ${'quadraginmilliatillion'}
${50001n} | ${'quinquaginmilliatillion'}
${60001n} | ${'sexaginmilliatillion'}
${70001n} | ${'septuaginmilliatillion'}
${80001n} | ${'octoginmilliatillion'}
${90001n} | ${'nonaginmilliatillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getKiloName(thousandPower)).toBe(name)
expect(getShortKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${100001} | ${'cenmilliatillion'}
${200001} | ${'duocenmilliatillion'}
${300001} | ${'trecenmilliatillion'}
${400001} | ${'quadringenmilliatillion'}
${500001} | ${'quingenmilliatillion'}
${600001} | ${'sescenmilliatillion'}
${700001} | ${'septingenmilliatillion'}
${800001} | ${'octingenmilliatillion'}
${900001} | ${'nongenmilliatillion'}
${100001n} | ${'cenmilliatillion'}
${200001n} | ${'duocenmilliatillion'}
${300001n} | ${'trecenmilliatillion'}
${400001n} | ${'quadringenmilliatillion'}
${500001n} | ${'quingenmilliatillion'}
${600001n} | ${'sescenmilliatillion'}
${700001n} | ${'septingenmilliatillion'}
${800001n} | ${'octingenmilliatillion'}
${900001n} | ${'nongenmilliatillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getKiloName(thousandPower)).toBe(name)
expect(getShortKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${1000001} | ${'milliamilliatillion'}
${2000001} | ${'duomilliamilliatillion'}
${3000001} | ${'tremilliamilliatillion'}
${4000001} | ${'quattuormilliamilliatillion'}
${5000001} | ${'quinmilliamilliatillion'}
${6000001} | ${'sexmilliamilliatillion'}
${7000001} | ${'septenmilliamilliatillion'}
${8000001} | ${'octomilliamilliatillion'}
${9000001} | ${'novemmilliamilliatillion'}
${1000001n} | ${'milliamilliatillion'}
${2000001n} | ${'duomilliamilliatillion'}
${3000001n} | ${'tremilliamilliatillion'}
${4000001n} | ${'quattuormilliamilliatillion'}
${5000001n} | ${'quinmilliamilliatillion'}
${6000001n} | ${'sexmilliamilliatillion'}
${7000001n} | ${'septenmilliamilliatillion'}
${8000001n} | ${'octomilliamilliatillion'}
${9000001n} | ${'novemmilliamilliatillion'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getKiloName(thousandPower)).toBe(name)
expect(getShortKiloName(thousandPower)).toBe(name)
})

+ 8
- 8
src/systems/en/getShortKiloName.ts 查看文件

@@ -1,18 +1,18 @@
import { GetKiloName } from '../../NumberSystem'
import NAMES from './names.json'
import { GetKiloName, Digit } from '../../common'
import NAMES from './names'
import getKiloCombiningPrefix from './base/kilo/combiningPrefix'

const getKiloName: GetKiloName = (thousandPower) => {
if (thousandPower === 0) {
if (thousandPower === 0n) {
return ''
}
if (thousandPower === 1) {
if (thousandPower === 1n) {
return NAMES.thousand
}
const kilo = thousandPower - 1
const kiloHundreds = Math.floor(kilo / 100)
const kiloTens = Math.floor((kilo / 10) % 10)
const kiloOnes = Math.floor(kilo % 10)
const kilo = thousandPower - 1n
const kiloHundreds = kilo / 100n
const kiloTens = (Number(kilo / 10n) % 10) as Digit
const kiloOnes = (Number(kilo) % 10) as Digit

return getKiloCombiningPrefix(kiloHundreds, kiloTens, kiloOnes) + NAMES.kiloEvenSuffix
}


+ 18
- 0
src/systems/en/index.ts 查看文件

@@ -0,0 +1,18 @@
import { NumberSystem } from '../../common'
import getKiloCount from './getKiloCount'
import getLongKiloName from './getLongKiloName'
import getEuropeanLongKiloName from './getEuropeanLongKiloName'
import getShortKiloName from './getShortKiloName'
import joinKilo from './joinKilo'

const numberSystem: NumberSystem = {
getKiloCount,
getKiloName: {
short: getShortKiloName,
long: getLongKiloName,
europeanLong: getEuropeanLongKiloName,
},
joinKilo,
}

export default numberSystem

+ 5
- 0
src/systems/en/joinKilo.ts 查看文件

@@ -0,0 +1,5 @@
import { JoinKilo } from '../../common'

const joinKilo: JoinKilo = (kiloCount, kiloName) => (kiloName ? [kiloCount, kiloName].join(' ') : kiloCount)

export default joinKilo

+ 0
- 92
src/systems/en/names.json 查看文件

@@ -1,92 +0,0 @@
{
"units": [
"zero",
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine"
],
"tenPlus": [
"ten",
"eleven",
"twelve",
"thirteen",
"fourteen",
"fifteen",
"sixteen",
"seventeen",
"eighteen",
"nineteen"
],
"tenTimes": [
"zero",
"ten",
"twenty",
"thirty",
"forty",
"fifty",
"sixty",
"seventy",
"eighty",
"ninety"
],
"hundred": "hundred",
"thousand": "thousand",
"kiloSpecialUnits": [
"",
"m",
"b",
"tr",
"quadr",
"quin",
"sex",
"sept",
"oct",
"non"
],
"kiloUnits": [
"",
"un",
"duo",
"tre",
"quattuor",
"quin",
"sex",
"septen",
"octo",
"novem"
],
"kiloTens": [
"",
"dec",
"vigin",
"trigin",
"quadragin",
"quinquagin",
"sexagin",
"septuagin",
"octogin",
"nonagin"
],
"kiloHundreds": [
"",
"cen",
"duocen",
"trecen",
"quadringen",
"quingen",
"sescen",
"septingen",
"octingen",
"nongen"
],
"kiloThousand": "millia",
"kiloEvenSuffix": "llion",
"kiloOddSuffix": "lliard",
"and": "and"
}

+ 30
- 0
src/systems/en/names.ts 查看文件

@@ -0,0 +1,30 @@
import { NumberSystemNameTable } from '../../common'

const names: NumberSystemNameTable = {
units: ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'],
tenPlus: [
'ten',
'eleven',
'twelve',
'thirteen',
'fourteen',
'fifteen',
'sixteen',
'seventeen',
'eighteen',
'nineteen',
],
tenTimes: ['zero', 'ten', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'],
hundred: 'hundred',
thousand: 'thousand',
kiloSpecialUnits: ['', 'm', 'b', 'tr', 'quadr', 'quin', 'sex', 'sept', 'oct', 'non'],
kiloUnits: ['', 'un', 'duo', 'tre', 'quattuor', 'quin', 'sex', 'septen', 'octo', 'novem'],
kiloTens: ['', 'dec', 'vigin', 'trigin', 'quadragin', 'quinquagin', 'sexagin', 'septuagin', 'octogin', 'nonagin'],
kiloHundreds: ['', 'cen', 'duocen', 'trecen', 'quadringen', 'quingen', 'sescen', 'septingen', 'octingen', 'nongen'],
kiloThousand: 'millia',
kiloEvenSuffix: 'llion',
kiloOddSuffix: 'lliard',
and: 'and',
}

export default names

+ 4
- 3
src/systems/tl/base/hundredTimes.ts 查看文件

@@ -1,7 +1,8 @@
import NAMES from '../names.json'
import { Digit } from '../../../common'
import NAMES from '../names'

interface HundredTimes {
(x100: number): string
(x100: Digit): string
}

/**
@@ -19,7 +20,7 @@ const hundredTimes: HundredTimes = (x100) => {
let infix: string
let hundredSuffixCombining: string

switch (x100) {
switch (Number(x100)) {
case 1:
hundredFactorCombining = hundredFactor.slice(1)
infix = 'n'


+ 65
- 65
src/systems/tl/base/kilo/combiningPrefix.test.ts 查看文件

@@ -8,8 +8,8 @@ it('should be a callable', () => {
expect(typeof combiningPrefix).toBe('function')
})

it('should accept 4 arguments', () => {
expect(combiningPrefix).toHaveLength(4)
it('should accept a minimum of 3 arguments', () => {
expect(combiningPrefix).toHaveLength(3)
})

describe('on 0 in hundreds place', () => {
@@ -26,7 +26,7 @@ describe('on 0 in hundreds place', () => {
${8} | ${'8'} | ${'okti'}
${9} | ${'9'} | ${'noni'}
`('should return "$name" on $display', ({ value, name }) => {
expect(combiningPrefix(0, 0, value)).toBe(name)
expect(combiningPrefix(0n, 0, value)).toBe(name)
})
})

@@ -55,22 +55,22 @@ describe('on 0 in hundreds place', () => {
${8} | ${'okto' + tensName}
${9} | ${'nobem' + tensName}
`(`should return "$display" for ${tens}$ones`, ({ ones, display }) => {
expect(combiningPrefix(0, tens, ones)).toBe(display)
expect(combiningPrefix(0n, tens, ones)).toBe(display)
})
})
})

describe.each`
hundreds | hundredsName
${1} | ${'sen'}
${2} | ${'duwosen'}
${3} | ${'tresen'}
${4} | ${'kuwadringhen'}
${5} | ${'kuwinghen'}
${6} | ${'sesen'}
${7} | ${'septinghen'}
${8} | ${'oktinghen'}
${9} | ${'nonghen'}
${1n} | ${'sen'}
${2n} | ${'duwosen'}
${3n} | ${'tresen'}
${4n} | ${'kuwadringhen'}
${5n} | ${'kuwinghen'}
${6n} | ${'sesen'}
${7n} | ${'septinghen'}
${8n} | ${'oktinghen'}
${9n} | ${'nonghen'}
`('on $hundreds in hundreds place', ({ hundreds, hundredsName }) => {
describe.each`
tens | tensName
@@ -105,74 +105,74 @@ describe.each`

describe.each`
hundredThousands | hundredThousandsName
${1} | ${'sen'}
${2} | ${'duwosen'}
${3} | ${'tresen'}
${4} | ${'kuwadringhen'}
${5} | ${'kuwinghen'}
${6} | ${'sesen'}
${7} | ${'septinghen'}
${8} | ${'oktinghen'}
${9} | ${'nonghen'}
${1n} | ${'sen'}
${2n} | ${'duwosen'}
${3n} | ${'tresen'}
${4n} | ${'kuwadringhen'}
${5n} | ${'kuwinghen'}
${6n} | ${'sesen'}
${7n} | ${'septinghen'}
${8n} | ${'oktinghen'}
${9n} | ${'nonghen'}
`('on $hundredThousands in hundred thousands place', ({ hundredThousands, hundredThousandsName }) => {
describe.each`
tenThousands | tenThousandsName
${0} | ${''}
${1} | ${'des'}
${2} | ${'bihin'}
${3} | ${'trihin'}
${4} | ${'kuwadrahin'}
${5} | ${'kuwinkuwahin'}
${6} | ${'seksahin'}
${7} | ${'septuwahin'}
${8} | ${'oktohin'}
${9} | ${'nonahin'}
${0n} | ${''}
${1n} | ${'des'}
${2n} | ${'bihin'}
${3n} | ${'trihin'}
${4n} | ${'kuwadrahin'}
${5n} | ${'kuwinkuwahin'}
${6n} | ${'seksahin'}
${7n} | ${'septuwahin'}
${8n} | ${'oktohin'}
${9n} | ${'nonahin'}
`('on $tenThousands in ten thousands place', ({ tenThousands, tenThousandsName }) => {
test.each`
thousands | display | name
${0} | ${hundredThousands + '' + tenThousands + '0000'} | ${hundredThousandsName + tenThousandsName + 'milyati'}
${1000} | ${hundredThousands + '' + tenThousands + '1000'} | ${hundredThousandsName + 'un' + tenThousandsName + 'milyati'}
${2000} | ${hundredThousands + '' + tenThousands + '2000'} | ${hundredThousandsName + 'duwo' + tenThousandsName + 'milyati'}
${3000} | ${hundredThousands + '' + tenThousands + '3000'} | ${hundredThousandsName + 'tre' + tenThousandsName + 'milyati'}
${4000} | ${hundredThousands + '' + tenThousands + '4000'} | ${hundredThousandsName + 'kuwatuwor' + tenThousandsName + 'milyati'}
${5000} | ${hundredThousands + '' + tenThousands + '5000'} | ${hundredThousandsName + 'kuwin' + tenThousandsName + 'milyati'}
${6000} | ${hundredThousands + '' + tenThousands + '6000'} | ${hundredThousandsName + 'seks' + tenThousandsName + 'milyati'}
${7000} | ${hundredThousands + '' + tenThousands + '7000'} | ${hundredThousandsName + 'septen' + tenThousandsName + 'milyati'}
${8000} | ${hundredThousands + '' + tenThousands + '8000'} | ${hundredThousandsName + 'okto' + tenThousandsName + 'milyati'}
${9000} | ${hundredThousands + '' + tenThousands + '9000'} | ${hundredThousandsName + 'nobem' + tenThousandsName + 'milyati'}
${0n} | ${hundredThousands + '' + tenThousands + '0000'} | ${hundredThousandsName + tenThousandsName + 'milyati'}
${1000n} | ${hundredThousands + '' + tenThousands + '1000'} | ${hundredThousandsName + 'un' + tenThousandsName + 'milyati'}
${2000n} | ${hundredThousands + '' + tenThousands + '2000'} | ${hundredThousandsName + 'duwo' + tenThousandsName + 'milyati'}
${3000n} | ${hundredThousands + '' + tenThousands + '3000'} | ${hundredThousandsName + 'tre' + tenThousandsName + 'milyati'}
${4000n} | ${hundredThousands + '' + tenThousands + '4000'} | ${hundredThousandsName + 'kuwatuwor' + tenThousandsName + 'milyati'}
${5000n} | ${hundredThousands + '' + tenThousands + '5000'} | ${hundredThousandsName + 'kuwin' + tenThousandsName + 'milyati'}
${6000n} | ${hundredThousands + '' + tenThousands + '6000'} | ${hundredThousandsName + 'seks' + tenThousandsName + 'milyati'}
${7000n} | ${hundredThousands + '' + tenThousands + '7000'} | ${hundredThousandsName + 'septen' + tenThousandsName + 'milyati'}
${8000n} | ${hundredThousands + '' + tenThousands + '8000'} | ${hundredThousandsName + 'okto' + tenThousandsName + 'milyati'}
${9000n} | ${hundredThousands + '' + tenThousands + '9000'} | ${hundredThousandsName + 'nobem' + tenThousandsName + 'milyati'}
`(`should return "$name" for $display`, ({ thousands, name }) => {
const kiloHundreds = hundredThousands * 1000 + tenThousands * 100 + thousands / 100
const kiloHundreds = hundredThousands * 1000n + tenThousands * 100n + thousands / 100n
expect(combiningPrefix(kiloHundreds, 0, 0)).toBe(name)
})
})
})

it.each`
test.each`
value | display | name
${1} | ${'1000000'} | ${'milyamilyati'}
${2} | ${'2000000'} | ${'duwomilyamilyati'}
${3} | ${'3000000'} | ${'tremilyamilyati'}
${4} | ${'4000000'} | ${'kuwatuwormilyamilyati'}
${5} | ${'5000000'} | ${'kuwinmilyamilyati'}
${6} | ${'6000000'} | ${'seksmilyamilyati'}
${7} | ${'7000000'} | ${'septenmilyamilyati'}
${8} | ${'8000000'} | ${'oktomilyamilyati'}
${9} | ${'9000000'} | ${'nobemmilyamilyati'}
${1n} | ${'1000000'} | ${'milyamilyati'}
${2n} | ${'2000000'} | ${'duwomilyamilyati'}
${3n} | ${'3000000'} | ${'tremilyamilyati'}
${4n} | ${'4000000'} | ${'kuwatuwormilyamilyati'}
${5n} | ${'5000000'} | ${'kuwinmilyamilyati'}
${6n} | ${'6000000'} | ${'seksmilyamilyati'}
${7n} | ${'7000000'} | ${'septenmilyamilyati'}
${8n} | ${'8000000'} | ${'oktomilyamilyati'}
${9n} | ${'9000000'} | ${'nobemmilyamilyati'}
`('should return "$name" on $display', ({ value, name }) => {
expect(combiningPrefix(value * 10000, 0, 0)).toBe(name)
expect(combiningPrefix(value * 10000n, 0, 0)).toBe(name)
})

it.each`
test.each`
value | display | name
${1} | ${'1001000'} | ${'milyamilyaunmilyati'}
${2} | ${'2002000'} | ${'duwomilyamilyaduwomilyati'}
${3} | ${'3003000'} | ${'tremilyamilyatremilyati'}
${4} | ${'4004000'} | ${'kuwatuwormilyamilyakuwatuwormilyati'}
${5} | ${'5005000'} | ${'kuwinmilyamilyakuwinmilyati'}
${6} | ${'6006000'} | ${'seksmilyamilyaseksmilyati'}
${7} | ${'7007000'} | ${'septenmilyamilyaseptenmilyati'}
${8} | ${'8008000'} | ${'oktomilyamilyaoktomilyati'}
${9} | ${'9009000'} | ${'nobemmilyamilyanobemmilyati'}
${1n} | ${'1001000'} | ${'milyamilyaunmilyati'}
${2n} | ${'2002000'} | ${'duwomilyamilyaduwomilyati'}
${3n} | ${'3003000'} | ${'tremilyamilyatremilyati'}
${4n} | ${'4004000'} | ${'kuwatuwormilyamilyakuwatuwormilyati'}
${5n} | ${'5005000'} | ${'kuwinmilyamilyakuwinmilyati'}
${6n} | ${'6006000'} | ${'seksmilyamilyaseksmilyati'}
${7n} | ${'7007000'} | ${'septenmilyamilyaseptenmilyati'}
${8n} | ${'8008000'} | ${'oktomilyamilyaoktomilyati'}
${9n} | ${'9009000'} | ${'nobemmilyamilyanobemmilyati'}
`('should return "$name" on $display', ({ value, name }) => {
expect(combiningPrefix(value * 10010, 0, 0)).toBe(name)
expect(combiningPrefix(value * 10010n, 0, 0)).toBe(name)
})

+ 34
- 23
src/systems/tl/base/kilo/combiningPrefix.ts 查看文件

@@ -1,63 +1,74 @@
import NAMES from '../../names.json'
import { Digit } from '../../../../common'
import NAMES from '../../names'
import ones from './ones'
import tens from './tens'
import hundreds from './hundreds'

interface CombiningPrefix {
(kiloHundreds: number, kiloTens: number, kiloOnes: number, kiloPower?: number): string
(kiloHundreds: bigint, kiloTens: Digit, kiloOnes: Digit, kiloPower?: bigint): string
}

const combiningPrefix: CombiningPrefix = (kiloHundredsRaw, kiloTens, kiloOnes, kiloPower = 0) => {
let kiloHundreds = kiloHundredsRaw
const combiningPrefix: CombiningPrefix = (kiloHundreds, kiloTens, kiloOnes, kiloPower = 0n) => {
let currentKiloHundreds = kiloHundreds
let prefix = ''

const isMillia = kiloHundredsRaw >= 10
const isMillia = kiloHundreds >= 10n
if (isMillia) {
prefix += combiningPrefix(
Math.floor(kiloHundredsRaw / 1000),
Math.floor((kiloHundredsRaw / 100) % 10),
Math.floor((kiloHundredsRaw / 10) % 10),
kiloPower + 1,
kiloHundreds / 1000n,
(Number(kiloHundreds / 100n) % 10) as Digit,
(Number(kiloHundreds / 10n) % 10) as Digit,
kiloPower + 1n,
)
kiloHundreds = kiloHundredsRaw % 10
currentKiloHundreds = kiloHundreds % 10n
}

const hasHundreds = kiloHundreds > 0
const hasHundreds = currentKiloHundreds > 0n
if (hasHundreds) {
prefix += hundreds(kiloHundreds)
prefix += hundreds(Number(currentKiloHundreds % 10n) as Digit)
}

const kiloTensNumber = Number(kiloTens)
const kiloOnesNumber = Number(kiloOnes)

if (
kiloPower > 0 &&
((kiloHundreds === 0 && kiloTens === 0 && kiloOnes > 1) ||
((kiloHundreds > 0 || kiloTens > 0) && kiloOnes > 0) ||
(kiloHundreds === 0 && kiloTens === 0 && kiloOnes === 1 && prefix.endsWith(NAMES.kiloThousand)))
((currentKiloHundreds === 0n && kiloTensNumber === 0 && kiloOnesNumber > 1) ||
((currentKiloHundreds > 0n || kiloTensNumber > 0) && kiloOnesNumber > 0) ||
(currentKiloHundreds === 0n &&
kiloTensNumber === 0 &&
kiloOnesNumber === 1 &&
prefix.endsWith(NAMES.kiloThousand)))
) {
// http://www.isthe.com/chongo/tech/math/number/howhigh.html
// Section: Titanic size numbers < 10^3000003
prefix += ones(kiloOnes, false)
}
if (kiloPower === 0 && kiloOnes > 0) {
const special = kiloHundreds === 0 && kiloTens === 0
if (kiloPower === 0n && kiloOnesNumber) {
const special = currentKiloHundreds === 0n && kiloTensNumber === 0
prefix += ones(kiloOnes, special)
if (special && [5, 6].includes(kiloOnes)) {
if (special && [5, 6].includes(Number(kiloOnes))) {
prefix += 't'
}
}
if (kiloTens > 0) {
if (kiloTensNumber > 0) {
prefix += tens(kiloTens)
}

if (kiloPower > 0) {
if (!(kiloHundreds === 0 && kiloTens === 0 && kiloOnes === 0)) {
for (let p = 0; p < kiloPower; p += 1) {
if (kiloPower > 0n) {
if (!(currentKiloHundreds === 0n && kiloTensNumber === 0 && kiloOnesNumber === 0)) {
for (let p = 0n; p < kiloPower; p += 1n) {
prefix += NAMES.kiloThousand
}
}
return prefix
}

if ((kiloHundreds === 0 && kiloTens > 1) || (kiloHundreds > 0 && kiloTens !== 1) || kiloHundredsRaw >= 10) {
if (
(currentKiloHundreds === 0n && kiloTensNumber > 1) ||
(currentKiloHundreds > 0n && kiloTensNumber !== 1) ||
kiloHundreds >= 10
) {
prefix += 't'
}
return prefix + 'i'


+ 3
- 2
src/systems/tl/base/kilo/hundreds.ts 查看文件

@@ -1,7 +1,8 @@
import NAMES from '../../names.json'
import { Digit } from '../../../../common'
import NAMES from '../../names'

interface Hundreds {
(kiloHundreds: number): string
(kiloHundreds: Digit): string
}

const hundreds: Hundreds = (kiloHundreds) => NAMES.kiloHundreds[kiloHundreds]


+ 2
- 2
src/systems/tl/base/kilo/ones.test.ts 查看文件

@@ -8,8 +8,8 @@ it('should be a callable', () => {
expect(typeof ones).toBe('function')
})

it('should accept 2 arguments', () => {
expect(ones).toHaveLength(2)
it('should accept a minimum of 1 argument', () => {
expect(ones).toHaveLength(1)
})

describe('on ordinary units', () => {


+ 3
- 2
src/systems/tl/base/kilo/ones.ts 查看文件

@@ -1,7 +1,8 @@
import NAMES from '../../names.json'
import { Digit } from '../../../../common'
import NAMES from '../../names'

interface Ones {
(kiloOnes: number, special: boolean): string
(kiloOnes: Digit, special: boolean): string
}

const ones: Ones = (kiloOnes, special = false) =>


+ 3
- 2
src/systems/tl/base/kilo/tens.ts 查看文件

@@ -1,7 +1,8 @@
import NAMES from '../../names.json'
import { Digit } from '../../../../common'
import NAMES from '../../names'

interface Tens {
(kiloTens: number): string
(kiloTens: Digit): string
}

const tens: Tens = (kiloTens) => NAMES.kiloTens[kiloTens]


+ 3
- 2
src/systems/tl/base/ones.ts 查看文件

@@ -1,7 +1,8 @@
import NAMES from '../names.json'
import { Digit } from '../../../common'
import NAMES from '../names'

interface Ones {
(x1: number): string
(x1: Digit): string
}

/**


+ 4
- 3
src/systems/tl/base/tenPlus.ts 查看文件

@@ -1,7 +1,8 @@
import NAMES from '../names.json'
import { Digit } from '../../../common'
import NAMES from '../names'

interface TenPlus {
(ones: number): string
(ones: Digit): string
}

/**
@@ -9,6 +10,6 @@ interface TenPlus {
* @param {number} x1 - The number in the ones place.
* @returns {string} The name of the number plus ten.
*/
const tenPlus: TenPlus = (x1) => (x1 === 0 ? NAMES.tenTimes[1] : NAMES.tenPlus[x1])
const tenPlus: TenPlus = (x1) => (Number(x1) === 0 ? NAMES.tenTimes[1] : NAMES.tenPlus[x1])

export default tenPlus

+ 3
- 2
src/systems/tl/base/tenTimes.ts 查看文件

@@ -1,7 +1,8 @@
import NAMES from '../names.json'
import { Digit } from '../../../common'
import NAMES from '../names'

interface TenTimes {
(x10: number): string
(x10: Digit): string
}

/**


+ 3
- 2
src/systems/tl/construct/tens.ts 查看文件

@@ -1,10 +1,11 @@
import NAMES from '../names.json'
import { Digit } from '../../../common'
import NAMES from '../names'
import ones from '../base/ones'
import tenPlus from '../base/tenPlus'
import getBaseTenTimesName from '../base/tenTimes'

interface Tens {
(x10: number, x1: number): string
(x10: Digit, x1: Digit): string
}

const tens: Tens = (x10, x1) => {


+ 9
- 9
src/systems/tl/getKiloCount.test.ts 查看文件

@@ -46,15 +46,15 @@ describe.each`
test.each`
ones | tenPlusName
${0} | ${' at sampu'}
${1} | ${' labing-isa'}
${2} | ${' labindalawa'}
${3} | ${' labintatlo'}
${4} | ${' labing-apat'}
${5} | ${' labinlima'}
${6} | ${' labing-anim'}
${7} | ${' labimpito'}
${8} | ${' labingwalo'}
${9} | ${' labinsiyam'}
${1} | ${' at labing-isa'}
${2} | ${' at labindalawa'}
${3} | ${' at labintatlo'}
${4} | ${' at labing-apat'}
${5} | ${' at labinlima'}
${6} | ${' at labing-anim'}
${7} | ${' at labimpito'}
${8} | ${' at labingwalo'}
${9} | ${' at labinsiyam'}
`(`should return "${hundredsName}$tenPlusName" for ${hundreds}1$ones`, ({ ones, tenPlusName }) => {
expect(getKiloCount(hundreds, 1, ones)).toBe([hundredsName, tenPlusName].join(''))
})


+ 3
- 3
src/systems/tl/getKiloCount.ts 查看文件

@@ -1,5 +1,5 @@
import NAMES from './names.json'
import { GetKiloCount } from '../../NumberSystem'
import { GetKiloCount } from '../../common'
import NAMES from './names'
import constructTens from './construct/tens'
import hundredTimes from './base/hundredTimes'

@@ -14,7 +14,7 @@ const getKiloCount: GetKiloCount = (x100, x10, x1) => {
}
return [hundredTimes(x100), NAMES.and, constructTens(0, x1)].join(' ')
}
if (x1 === 0) {
if (x10 === 1 || x1 === 0) {
return [hundredTimes(x100), NAMES.and, constructTens(x10, x1)].join(' ')
}
return [hundredTimes(x100), constructTens(x10, x1)].join(' ')


+ 120
- 0
src/systems/tl/getShortKiloName.test.ts 查看文件

@@ -0,0 +1,120 @@
import getShortKiloName from './getShortKiloName'

it('should exist', () => {
expect(getShortKiloName).toBeDefined()
})

it('should be a callable', () => {
expect(typeof getShortKiloName).toBe('function')
})

it('should accept 1 argument', () => {
expect(getShortKiloName).toHaveLength(1)
})

test.each`
thousandPower | name
${0n} | ${''}
${1n} | ${'libo'}
${2n} | ${'milyon'}
${3n} | ${'bilyon'}
${4n} | ${'trilyon'}
${5n} | ${'kuwadrilyon'}
${6n} | ${'kuwintilyon'}
${7n} | ${'sekstilyon'}
${8n} | ${'septilyon'}
${9n} | ${'oktilyon'}
${10n} | ${'nonilyon'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getShortKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${11n} | ${'desilyon'}
${21n} | ${'bihintilyon'}
${31n} | ${'trihintilyon'}
${41n} | ${'kuwadrahintilyon'}
${51n} | ${'kuwinkuwahintilyon'}
${61n} | ${'seksahintilyon'}
${71n} | ${'septuwahintilyon'}
${81n} | ${'oktohintilyon'}
${91n} | ${'nonahintilyon'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getShortKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${101n} | ${'sentilyon'}
${201n} | ${'duwosentilyon'}
${301n} | ${'tresentilyon'}
${401n} | ${'kuwadringhentilyon'}
${501n} | ${'kuwinghentilyon'}
${601n} | ${'sesentilyon'}
${701n} | ${'septinghentilyon'}
${801n} | ${'oktinghentilyon'}
${901n} | ${'nonghentilyon'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getShortKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${1001n} | ${'milyatilyon'}
${2001n} | ${'duwomilyatilyon'}
${3001n} | ${'tremilyatilyon'}
${4001n} | ${'kuwatuwormilyatilyon'}
${5001n} | ${'kuwinmilyatilyon'}
${6001n} | ${'seksmilyatilyon'}
${7001n} | ${'septenmilyatilyon'}
${8001n} | ${'oktomilyatilyon'}
${9001n} | ${'nobemmilyatilyon'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getShortKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${10001n} | ${'desmilyatilyon'}
${20001n} | ${'bihinmilyatilyon'}
${30001n} | ${'trihinmilyatilyon'}
${40001n} | ${'kuwadrahinmilyatilyon'}
${50001n} | ${'kuwinkuwahinmilyatilyon'}
${60001n} | ${'seksahinmilyatilyon'}
${70001n} | ${'septuwahinmilyatilyon'}
${80001n} | ${'oktohinmilyatilyon'}
${90001n} | ${'nonahinmilyatilyon'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getShortKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${100001n} | ${'senmilyatilyon'}
${200001n} | ${'duwosenmilyatilyon'}
${300001n} | ${'tresenmilyatilyon'}
${400001n} | ${'kuwadringhenmilyatilyon'}
${500001n} | ${'kuwinghenmilyatilyon'}
${600001n} | ${'sesenmilyatilyon'}
${700001n} | ${'septinghenmilyatilyon'}
${800001n} | ${'oktinghenmilyatilyon'}
${900001n} | ${'nonghenmilyatilyon'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getShortKiloName(thousandPower)).toBe(name)
})

test.each`
thousandPower | name
${1000001n} | ${'milyamilyatilyon'}
${2000001n} | ${'duwomilyamilyatilyon'}
${3000001n} | ${'tremilyamilyatilyon'}
${4000001n} | ${'kuwatuwormilyamilyatilyon'}
${5000001n} | ${'kuwinmilyamilyatilyon'}
${6000001n} | ${'seksmilyamilyatilyon'}
${7000001n} | ${'septenmilyamilyatilyon'}
${8000001n} | ${'oktomilyamilyatilyon'}
${9000001n} | ${'nobemmilyamilyatilyon'}
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower }) => {
expect(getShortKiloName(thousandPower)).toBe(name)
})

+ 20
- 0
src/systems/tl/getShortKiloName.ts 查看文件

@@ -0,0 +1,20 @@
import { GetKiloName, Digit } from '../../common'
import NAMES from './names'
import getKiloCombiningPrefix from './base/kilo/combiningPrefix'

const getKiloName: GetKiloName = (thousandPower) => {
if (thousandPower === 0n) {
return ''
}
if (thousandPower === 1n) {
return NAMES.thousand
}
const kilo = thousandPower - 1n
const kiloHundreds = kilo / 100n
const kiloTens = (Number(kilo / 10n) % 10) as Digit
const kiloOnes = (Number(kilo) % 10) as Digit

return getKiloCombiningPrefix(kiloHundreds, kiloTens, kiloOnes) + NAMES.kiloEvenSuffix
}

export default getKiloName

+ 14
- 0
src/systems/tl/index.ts 查看文件

@@ -0,0 +1,14 @@
import { NumberSystem } from '../../common'
import getKiloCount from './getKiloCount'
import getShortKiloName from './getShortKiloName'
import joinKilo from './joinKilo'

const numberSystem: NumberSystem = {
getKiloCount,
getKiloName: {
short: getShortKiloName,
},
joinKilo,
}

export default numberSystem

+ 18
- 0
src/systems/tl/joinKilo.ts 查看文件

@@ -0,0 +1,18 @@
import { JoinKilo } from '../../common'

const joinKilo: JoinKilo = (kiloCount, kiloName) => {
const kiloCountLastLetter = kiloCount.slice(-1)
let kiloCountSuffix = ' na '

if (['a', 'o'].includes(kiloCountLastLetter)) {
kiloCountSuffix = 'ng '
}

if ('n' === kiloCountLastLetter) {
kiloCountSuffix = 'g '
}

return [kiloCount, kiloCountSuffix, kiloName].join('')
}

export default joinKilo

+ 0
- 92
src/systems/tl/names.json 查看文件

@@ -1,92 +0,0 @@
{
"units": [
"sero",
"isa",
"dalawa",
"tatlo",
"apat",
"lima",
"anim",
"pito",
"walo",
"siyam"
],
"tenPlus": [
"sampu",
"labing-isa",
"labindalawa",
"labintatlo",
"labing-apat",
"labinlima",
"labing-anim",
"labimpito",
"labingwalo",
"labinsiyam"
],
"tenTimes": [
"sero",
"sampu",
"dalawampu",
"tatlumpu",
"apatnapu",
"limampu",
"animnapu",
"pitumpu",
"walumpu",
"siyamnapu"
],
"hundred": "daan",
"thousand": "libo",
"kiloSpecialUnits": [
"",
"m",
"b",
"tr",
"kuwadr",
"kuwin",
"seks",
"sept",
"okt",
"non"
],
"kiloUnits": [
"",
"un",
"duwo",
"tre",
"kuwatuwor",
"kuwin",
"seks",
"septen",
"okto",
"nobem"
],
"kiloTens": [
"",
"des",
"bihin",
"trihin",
"kuwadrahin",
"kuwinkuwahin",
"seksahin",
"septuwahin",
"oktohin",
"nonahin"
],
"kiloHundreds": [
"",
"sen",
"duwosen",
"tresen",
"kuwadringhen",
"kuwinghen",
"sesen",
"septinghen",
"oktinghen",
"nonghen"
],
"kiloThousand": "milya",
"kiloEvenSuffix": "lyon",
"kiloOddSuffix": "lyard",
"and": "at"
}

+ 63
- 0
src/systems/tl/names.ts 查看文件

@@ -0,0 +1,63 @@
import { NumberSystemNameTable } from '../../common'

const names: NumberSystemNameTable = {
units: ['sero', 'isa', 'dalawa', 'tatlo', 'apat', 'lima', 'anim', 'pito', 'walo', 'siyam'],
tenPlus: [
'sampu',
'labing-isa',
'labindalawa',
'labintatlo',
'labing-apat',
'labinlima',
'labing-anim',
'labimpito',
'labingwalo',
'labinsiyam',
],
tenTimes: [
'sero',
'sampu',
'dalawampu',
'tatlumpu',
'apatnapu',
'limampu',
'animnapu',
'pitumpu',
'walumpu',
'siyamnapu',
],
hundred: 'daan',
thousand: 'libo',
kiloSpecialUnits: ['', 'm', 'b', 'tr', 'kuwadr', 'kuwin', 'seks', 'sept', 'okt', 'non'],
kiloUnits: ['', 'un', 'duwo', 'tre', 'kuwatuwor', 'kuwin', 'seks', 'septen', 'okto', 'nobem'],
kiloTens: [
'',
'des',
'bihin',
'trihin',
'kuwadrahin',
'kuwinkuwahin',
'seksahin',
'septuwahin',
'oktohin',
'nonahin',
],
kiloHundreds: [
'',
'sen',
'duwosen',
'tresen',
'kuwadringhen',
'kuwinghen',
'sesen',
'septinghen',
'oktinghen',
'nonghen',
],
kiloThousand: 'milya',
kiloEvenSuffix: 'lyon',
kiloOddSuffix: 'lyard',
and: 'at',
}

export default names

+ 1
- 0
tsconfig.json 查看文件

@@ -2,6 +2,7 @@
"include": ["src", "types"],
"compilerOptions": {
"module": "esnext",
"target": "ES2020",
"lib": ["dom", "esnext"],
"importHelpers": true,
"declaration": true,