Skip to content
This repository was archived by the owner on Jan 15, 2025. It is now read-only.

Commit 6fb70be

Browse files
authored
Support bigint arguments and safe integers (#92)
1 parent e3122c8 commit 6fb70be

File tree

3 files changed

+63
-9
lines changed

3 files changed

+63
-9
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [11.2.0] - 2024-03-29
11+
12+
### Changed
13+
14+
- The Decimal128 constructor now accepts BigInt arguments as well as safe integer Numbers
15+
1016
## [11.1.0] - 2024-03-29
1117

1218
### Changed

src/decimal128.mts

+26-8
Original file line numberDiff line numberDiff line change
@@ -1035,20 +1035,38 @@ export class Decimal128 {
10351035
private readonly isNegative: boolean;
10361036
private readonly rat;
10371037

1038-
constructor(n: string, options?: ConstructorOptions) {
1038+
constructor(n: string | number | bigint, options?: ConstructorOptions) {
10391039
let data = undefined;
1040+
let s = "";
10401041

10411042
let fullySpecifiedOptions =
10421043
ensureFullySpecifiedConstructorOptions(options);
10431044

1044-
if (n.match(nanRegExp)) {
1045+
if ("number" === typeof n) {
1046+
if (!Number.isInteger(n)) {
1047+
throw new SyntaxError("Non-integer number not permitted");
1048+
}
1049+
if (!Number.isSafeInteger(n)) {
1050+
throw new RangeError(
1051+
"Integer is too large to be exactly represented"
1052+
);
1053+
}
1054+
1055+
s = n.toString();
1056+
} else if ("bigint" === typeof n) {
1057+
s = n.toString();
1058+
} else {
1059+
s = n;
1060+
}
1061+
1062+
if (s.match(nanRegExp)) {
10451063
data = handleNan();
1046-
} else if (n.match(exponentRegExp)) {
1047-
data = handleExponentialNotation(n, fullySpecifiedOptions);
1048-
} else if (n.match(digitStrRegExp)) {
1049-
data = handleDecimalNotation(n, fullySpecifiedOptions);
1050-
} else if (n.match(infRegExp)) {
1051-
data = handleInfinity(n);
1064+
} else if (s.match(exponentRegExp)) {
1065+
data = handleExponentialNotation(s, fullySpecifiedOptions);
1066+
} else if (s.match(digitStrRegExp)) {
1067+
data = handleDecimalNotation(s, fullySpecifiedOptions);
1068+
} else if (s.match(infRegExp)) {
1069+
data = handleInfinity(s);
10521070
} else {
10531071
throw new SyntaxError(`Illegal number format "${n}"`);
10541072
}

tests/constructor.test.js

+31-1
Original file line numberDiff line numberDiff line change
@@ -588,5 +588,35 @@ describe("General Decimal Arithmetic specification", () => {
588588
).toStrictEqual("0E+2");
589589
});
590590
});
591-
describe("engineering string", () => {});
591+
});
592+
593+
describe("number arguments", () => {
594+
test("integer", () => {
595+
expect(new Decimal128(42).toString()).toStrictEqual("42");
596+
});
597+
test("non-integer number", () => {
598+
expect(() => new Decimal128(42.5)).toThrow(SyntaxError);
599+
});
600+
test("NaN", () => {
601+
expect(() => new Decimal128(NaN)).toThrow(SyntaxError);
602+
});
603+
test("minus zero", () => {
604+
expect(new Decimal128(-0).toString()).toStrictEqual("0");
605+
});
606+
test("too big", () => {
607+
expect(
608+
() => new Decimal128(123456789012345678901234567890123456789)
609+
).toThrow(RangeError);
610+
});
611+
});
612+
613+
describe("bigint", () => {
614+
test("simple", () => {
615+
expect(new Decimal128(42n).toString()).toStrictEqual("42");
616+
});
617+
test("too big", () => {
618+
expect(
619+
() => new Decimal128(123456789012345678901234567890123456789n)
620+
).toThrow(RangeError);
621+
});
592622
});

0 commit comments

Comments
 (0)