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

Commit 81f3c38

Browse files
committed
Convert to BigInt and Number
1 parent 10a4b5c commit 81f3c38

File tree

4 files changed

+138
-9
lines changed

4 files changed

+138
-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+
## [14.1.0] - 2024-05-06
11+
12+
### Added
13+
14+
- Support for converting decimals to BigInts and Numbers.
15+
1016
## [14.0.0] - 2024-04-30
1117

1218
### Removed

src/decimal128.mts

+46-9
Original file line numberDiff line numberDiff line change
@@ -668,15 +668,6 @@ const DEFAULT_CONSTRUCTOR_OPTIONS: FullySpecifiedConstructorOptions =
668668
normalize: CONSTRUCTOR_SHOULD_NORMALIZE,
669669
});
670670

671-
interface FullySpecifiedArithmeticOperationOptions {
672-
roundingMode: RoundingMode;
673-
}
674-
675-
const DEFAULT_ARITHMETIC_OPERATION_OPTIONS: FullySpecifiedArithmeticOperationOptions =
676-
Object.freeze({
677-
roundingMode: ROUNDING_MODE_DEFAULT,
678-
});
679-
680671
type ToStringFormat = "decimal" | "exponential";
681672
const TOSTRING_FORMATS: string[] = ["decimal", "exponential"];
682673

@@ -938,6 +929,52 @@ export class Decimal128 {
938929
return this.emitDecimal(options);
939930
}
940931

932+
private isInteger(): boolean {
933+
let s = this.toString();
934+
935+
let [_, rhs] = s.split(/[.]/);
936+
937+
if (rhs === undefined) {
938+
return true;
939+
}
940+
941+
return !!rhs.match(/^0+$/);
942+
}
943+
944+
toBigInt(): bigint {
945+
if (this.isNaN) {
946+
throw new RangeError("NaN cannot be converted to a BigInt");
947+
}
948+
949+
if (!this.isFinite) {
950+
throw new RangeError("Infinity cannot be converted to a BigInt");
951+
}
952+
953+
if (!this.isInteger()) {
954+
throw new RangeError(
955+
"Non-integer decimal cannot be converted to a BigInt"
956+
);
957+
}
958+
959+
return BigInt(this.toString());
960+
}
961+
962+
toNumber(): number {
963+
if (this.isNaN) {
964+
return NaN;
965+
}
966+
967+
if (!this.isFinite) {
968+
if (this.isNegative) {
969+
return -Infinity;
970+
}
971+
972+
return Infinity;
973+
}
974+
975+
return Number(this.toString());
976+
}
977+
941978
/**
942979
* Compare two values. Return
943980
*

tests/tobigint.test.js

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { Decimal128 } from "../src/decimal128.mjs";
2+
import { expectDecimal128 } from "./util.js";
3+
4+
describe("NaN", () => {
5+
test("does not work", () => {
6+
expect(() => new Decimal128("NaN").toBigInt()).toThrow(RangeError);
7+
});
8+
});
9+
10+
describe("zero", () => {
11+
test("positive zero", () => {
12+
expect(new Decimal128("0").toBigInt()).toStrictEqual(0n);
13+
});
14+
test("negative zero", () => {
15+
expect(new Decimal128("-0").toBigInt()).toStrictEqual(0n);
16+
});
17+
});
18+
19+
describe("infinity", () => {
20+
test("positive", () => {
21+
expect(() => new Decimal128("Infinity").toBigInt()).toThrow(RangeError);
22+
});
23+
test("negative", () => {
24+
expect(() => new Decimal128("-Infinity").toBigInt()).toThrow(
25+
RangeError
26+
);
27+
});
28+
});
29+
30+
describe("non-integer", () => {
31+
test("throws", () => {
32+
expect(() => new Decimal128("1.2").toBigInt()).toThrow(RangeError);
33+
});
34+
test("work with mathematical value (ignore trailing zeroes)", () => {
35+
expect(new Decimal128("1.00").toBigInt()).toStrictEqual(1n);
36+
});
37+
});
38+
39+
describe("simple examples", () => {
40+
test("42", () => {
41+
expect(new Decimal128("42").toBigInt()).toStrictEqual(42n);
42+
});
43+
test("-123", () => {
44+
expect(new Decimal128("-123").toBigInt()).toStrictEqual(-123n);
45+
});
46+
});

tests/tonumber.test.js

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { Decimal128 } from "../src/decimal128.mjs";
2+
import { expectDecimal128 } from "./util.js";
3+
4+
describe("NaN", () => {
5+
test("works", () => {
6+
expect(new Decimal128("NaN").toNumber()).toStrictEqual(NaN);
7+
});
8+
});
9+
10+
describe("zero", () => {
11+
test("positive zero", () => {
12+
expect(new Decimal128("0").toNumber()).toStrictEqual(0);
13+
});
14+
test("negative zero", () => {
15+
expect(new Decimal128("-0").toNumber()).toStrictEqual(-0);
16+
});
17+
});
18+
19+
describe("infinity", () => {
20+
test("positive infinity", () => {
21+
expect(new Decimal128("Infinity").toNumber()).toStrictEqual(Infinity);
22+
});
23+
test("negative infinity", () => {
24+
expect(new Decimal128("-Infinity").toNumber()).toStrictEqual(-Infinity);
25+
});
26+
});
27+
28+
describe("simple examples", () => {
29+
test("1.25", () => {
30+
expect(new Decimal128("1.25").toNumber()).toStrictEqual(1.25);
31+
});
32+
test("0.1", () => {
33+
expect(new Decimal128("0.1").toNumber()).toStrictEqual(0.1);
34+
});
35+
test("extreme precision", () => {
36+
expect(
37+
new Decimal128("0." + "0".repeat(100) + "1").toNumber()
38+
).toStrictEqual(1e-101);
39+
});
40+
});

0 commit comments

Comments
 (0)