yaejunyang/packages/utils/integerKorean.ts

141 lines
3.2 KiB
TypeScript

export default class IntegerKorean {
static DigitName = [
"영",
"일",
"이",
"삼",
"사",
"오",
"육",
"칠",
"팔",
"구",
];
static DigitModifier = ["", "십", "백", "천"];
static Unit = [
"",
"만",
"억",
"조",
"경",
"해",
"자",
"양",
"구",
"간",
"정",
"재",
"극",
"항하사",
"아승기",
"나유타",
"불가사의",
"무량대수",
];
private static stringifyKDigits(
first: number,
second: number,
third: number,
forth: number,
): string {
const buf = [];
if (forth) {
if (forth >= 2) buf.push(this.DigitName[forth]);
buf.push(this.DigitModifier[3]);
}
if (third) {
if (third >= 2) buf.push(this.DigitName[third]);
buf.push(this.DigitModifier[2]);
}
if (second) {
if (second >= 2) buf.push(this.DigitName[second]);
buf.push(this.DigitModifier[1]);
}
if (first || (!forth && !third && !second)) {
buf.push(this.DigitName[first]);
}
return buf.join("");
}
private static parseKDigitsFromNumber(num: number): string {
const first = num % 10;
const second = Math.floor(num / 10) % 10;
const third = Math.floor(num / 100) % 10;
const forth = Math.floor(num / 1000) % 10;
return this.stringifyKDigits(first, second, third, forth);
}
private static parseKDigitsFromString(num: string, offset: number): string {
const first = +num[offset]!;
const second = offset >= 1 ? +num[offset - 1]! : 0;
const third = offset >= 2 ? +num[offset - 2]! : 0;
const forth = offset >= 3 ? +num[offset - 3]! : 0;
return this.stringifyKDigits(first, second, third, forth);
}
static convertFromString(num: string): string {
num = num.replace(/,/g, "");
let isNegative = false;
if (num.startsWith("-")) {
num = num.slice(1, -1);
isNegative = true;
}
if (num == "0") {
return isNegative ? "마이너스영" : "영";
}
const unitStack = [];
let offset = num.length - 1;
while (offset >= 0) {
unitStack.push(this.parseKDigitsFromString(num, offset));
offset -= 4;
}
const buf = [];
if (isNegative) buf.push("마이너스");
for (let i = unitStack.length - 1; i >= 0; i--) {
const currUnit = this.Unit[i] ?? "";
let currKDigits = unitStack[i] ?? "";
if (currKDigits == "영") continue;
if (i == 1 && currKDigits == "일") currKDigits = "";
buf.push(currKDigits + currUnit);
}
return buf.join("");
}
static convertFromNumber(num: number): string {
let isNegative = false;
if (num < 0) {
isNegative = true;
num *= -1;
}
if (num == 0) {
return "영";
}
const unitStack = [];
while (num) {
unitStack.push(this.parseKDigitsFromNumber(num));
num = Math.floor(num / 10000);
}
const buf = [];
if (isNegative) buf.push("마이너스");
for (let i = unitStack.length - 1; i >= 0; i--) {
const currUnit = this.Unit[i] ?? "";
let currKDigits = unitStack[i] ?? "";
if (currKDigits == "영") continue;
if (i == 1 && currKDigits == "일") currKDigits = "";
buf.push(currKDigits + currUnit);
}
return buf.join("");
}
}