diff --git a/CHANGELOG.md b/CHANGELOG.md index 03e26af..65b2954 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # @greenlabs/rescript-korean-numeral +## 0.4.0 + +### Breaking Changes + +- ReScript v11.1 BigInt 지원 +- fromInt64 API 제거 +- fromString 함수의 반환 타입 변경: `string` -> `option` + +## 0.3.0 + +- ReScript v11 지원 + ## 0.2.0 ### Minor Changes diff --git a/__tests__/KoreanNumeral_test.res b/__tests__/KoreanNumeral_test.res index 14723cb..46d392b 100644 --- a/__tests__/KoreanNumeral_test.res +++ b/__tests__/KoreanNumeral_test.res @@ -4,15 +4,15 @@ describe(`1만 이하 표시`, () => { open Expect test(`KoreanNumeral.fromInt`, () => { - let result = KoreanNumeral.fromInt(1234, ()) + let result = KoreanNumeral.fromInt(1234) expect(result)->toBe(`1,234`) }) test(`KoreanNumeral.fromFloat`, () => { - let result = KoreanNumeral.fromFloat(152212525110.0, ()) + let result = KoreanNumeral.fromFloat(152212525110.0) expect(result)->toBe(`1,522억 1,252만 5,110`) }) - test(`KoreanNumeral.fromInt64`, () => { - let result = KoreanNumeral.fromInt64(Int64.of_string("1234567890987654321"), ()) + test(`KoreanNumeral.fromBigInt`, () => { + let result = KoreanNumeral.fromBigInt(1234567890987654321n) expect(result)->toBe(`123경 4,567조 8,909억 8,765만 4,321`) }) }) @@ -21,35 +21,51 @@ describe(`1만 이하는 절삭`, () => { open Expect test(`1234 => ""`, () => { - let result = KoreanNumeral.fromInt(1234, ~drop=1, ()) + let result = KoreanNumeral.fromInt(1234, ~drop=1) expect(result)->toBe(``) }) test(`1234567 => "123만"`, () => { - let result = KoreanNumeral.fromInt(1234567, ~drop=1, ()) + let result = KoreanNumeral.fromInt(1234567, ~drop=1) expect(result)->toBe(`123만`) }) test(`1234567890 => "12억 3,456만"`, () => { - let result = KoreanNumeral.fromInt(1234567890, ~drop=1, ()) + let result = KoreanNumeral.fromInt(1234567890, ~drop=1) expect(result)->toBe(`12억 3,456만`) }) test(`1234567890.1 => "12억 3,456만"`, () => { - let result = KoreanNumeral.fromFloat(1234567890.1, ~drop=1, ()) + let result = KoreanNumeral.fromFloat(1234567890.1, ~drop=1) expect(result)->toBe(`12억 3,456만`) }) test(`152212525110 => "1,522억 1,252만"`, () => { - let result = KoreanNumeral.fromFloat(152212525110.0, ~drop=1, ()) + let result = KoreanNumeral.fromFloat(152212525110.0, ~drop=1) expect(result)->toBe(`1,522억 1,252만`) }) test(`152212525110 => "1,522억"`, () => { - let result = KoreanNumeral.fromFloat(152200005110.0, ~drop=1, ()) + let result = KoreanNumeral.fromFloat(152200005110.0, ~drop=1) expect(result)->toBe(`1,522억`) }) test(`220000152212525110.0 => "22경 1,522억 1,252만"`, () => { - let result = KoreanNumeral.fromFloat(220000152212525110.0, ~drop=1, ()) + let result = KoreanNumeral.fromFloat(220000152212525110.0, ~drop=1) expect(result)->toBe(`22경 1,522억 1,252만`) }) test(`1234567890987654321 => "123경 4,567조 8,909억 8,765만"`, () => { - let result = KoreanNumeral.fromString("1234567890987654321", ~drop=1, ()) + let result = KoreanNumeral.fromString("1234567890987654321a", ~drop=1) + expect(result)->toBe(None) + }) + test(`152212525110n => "1,522억 1,252만"`, () => { + let result = KoreanNumeral.fromBigInt(152212525110n, ~drop=1) + expect(result)->toBe(`1,522억 1,252만`) + }) + test(`152212525110n => "1,522억"`, () => { + let result = KoreanNumeral.fromBigInt(152200005110n, ~drop=1) + expect(result)->toBe(`1,522억`) + }) + test(`220000152212525110n => "22경 1,522억 1,252만"`, () => { + let result = KoreanNumeral.fromBigInt(220000152212525110n, ~drop=1) + expect(result)->toBe(`22경 1,522억 1,252만`) + }) + test(`1234567890987654321n => "123경 4,567조 8,909억 8,765만"`, () => { + let result = KoreanNumeral.fromBigInt(1234567890987654321n, ~drop=1) expect(result)->toBe(`123경 4,567조 8,909억 8,765만`) }) }) diff --git a/src/KoreanNumeral.res b/src/KoreanNumeral.res index 954d643..7d28906 100644 --- a/src/KoreanNumeral.res +++ b/src/KoreanNumeral.res @@ -3,17 +3,21 @@ open Belt let unitsInKorean = list{``, `만`, `억`, `조`, `경`} -let mann = Int64.of_int(10000) +let mann = 10000n -let rec split = divided => - Int64.equal(divided, Int64.zero) - ? list{} - : list{Int64.rem(divided, mann), ...split(Int64.div(divided, mann))} +let rec split = divided => { + open! Js.BigInt + if divided == 0n { + list{} + } else { + list{Js.BigInt.mod(divided, mann), ...split(divided / mann)} + } +} -let fromInt64 = (num, ~drop=0, ()) => { +let fromBigInt = (num, ~drop=0) => { split(num) ->List.zipBy(unitsInKorean, (num, unit) => { - Int64.equal(num, Int64.zero) ? "" : num->Int64.to_int->toLocaleString("ko-KR") ++ unit + num == 0n ? "" : num->Js.BigInt.toLocaleString ++ unit }) ->List.drop(drop) ->Option.getWithDefault(list{}) @@ -23,14 +27,18 @@ let fromInt64 = (num, ~drop=0, ()) => { ->(Js.Array.joinWith(" ", _)) } -let fromInt = (num, ~drop=0, ()) => { - fromInt64(Int64.of_int(num), ~drop, ()) +let fromInt = (num, ~drop=0) => { + num->Int.toString->Js.BigInt.fromStringExn->fromBigInt(~drop) } -let fromFloat = (num, ~drop=0, ()) => { - fromInt64(Int64.of_float(ceil(num)), ~drop, ()) +let fromFloat = (num, ~drop=0) => { + num->ceil->Float.toString->Js.BigInt.fromStringExn->fromBigInt(~drop) } -let fromString = (num, ~drop=0, ()) => { - fromInt64(Int64.of_string(num), ~drop, ()) +let fromString = (num, ~drop=0) => { + try { + num->Js.BigInt.fromStringExn->fromBigInt(~drop)->Some + } catch { + | _ => None + } }