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
@@ -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", | |||
@@ -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: | |||
@@ -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() | |||
} | |||
} |
@@ -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 | |||
} | |||
} |
@@ -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 | |||
} |
@@ -1,11 +0,0 @@ | |||
export type Scale = 'long' | 'short' | |||
export interface ConvertOptions { | |||
scale?: Scale | |||
} | |||
export interface StreamOptions { | |||
encoding?: BufferEncoding | |||
} | |||
export type ReadStreamOptions = ConvertOptions & StreamOptions |
@@ -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 | |||
} |
@@ -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 |
@@ -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) | |||
}) |
@@ -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' | |||
@@ -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] | |||
@@ -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', () => { | |||
@@ -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) => | |||
@@ -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] | |||
@@ -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 | |||
} | |||
/** | |||
@@ -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 | |||
} | |||
/** | |||
@@ -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 | |||
} | |||
/** | |||
@@ -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) => { | |||
@@ -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) | |||
}) |
@@ -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 |
@@ -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 |
@@ -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) | |||
}) |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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" | |||
} |
@@ -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 |
@@ -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 |
@@ -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 | |||
} | |||
/** | |||
@@ -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) | |||
}) |
@@ -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' | |||
@@ -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] | |||
@@ -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', () => { | |||
@@ -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) => | |||
@@ -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] | |||
@@ -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 | |||
} | |||
/** | |||
@@ -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 | |||
} | |||
/** | |||
@@ -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 | |||
} | |||
/** | |||
@@ -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) => { | |||
@@ -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) | |||
}) |
@@ -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 |
@@ -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(' ') | |||
} | |||
@@ -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) | |||
}) |
@@ -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 |
@@ -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) | |||
}) |
@@ -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 | |||
} | |||
@@ -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 |
@@ -0,0 +1,5 @@ | |||
import { JoinKilo } from '../../common' | |||
const joinKilo: JoinKilo = (kiloCount, kiloName) => (kiloName ? [kiloCount, kiloName].join(' ') : kiloCount) | |||
export default joinKilo |
@@ -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" | |||
} |
@@ -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 |
@@ -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' | |||
@@ -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) | |||
}) |
@@ -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' | |||
@@ -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] | |||
@@ -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', () => { | |||
@@ -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) => | |||
@@ -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] | |||
@@ -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 | |||
} | |||
/** | |||
@@ -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 |
@@ -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 | |||
} | |||
/** | |||
@@ -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) => { | |||
@@ -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('')) | |||
}) | |||
@@ -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(' ') | |||
@@ -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) | |||
}) |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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" | |||
} |
@@ -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 |
@@ -2,6 +2,7 @@ | |||
"include": ["src", "types"], | |||
"compilerOptions": { | |||
"module": "esnext", | |||
"target": "ES2020", | |||
"lib": ["dom", "esnext"], | |||
"importHelpers": true, | |||
"declaration": true, | |||