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

Commit 378f8f6

Browse files
committed
Add tests for toPrecision
1 parent 07ec1f1 commit 378f8f6

File tree

3 files changed

+103
-23
lines changed

3 files changed

+103
-23
lines changed

src/decimal128.mts

+60-2
Original file line numberDiff line numberDiff line change
@@ -950,8 +950,66 @@ export class Decimal128 {
950950
return this.round(n).emitDecimal(opts);
951951
}
952952

953-
toPrecision(n?: number): string {
954-
return "6";
953+
toPrecision(opts?: { digits?: number }): string {
954+
if (undefined === opts || undefined === opts.digits) {
955+
return this.toString();
956+
}
957+
958+
let n = opts.digits;
959+
960+
if (n <= 0) {
961+
throw new RangeError("Argument must be positive");
962+
}
963+
964+
if (!Number.isInteger(n)) {
965+
throw new RangeError("Argument must be an integer");
966+
}
967+
968+
if (this.isNaN) {
969+
return "NaN";
970+
}
971+
972+
if (!this.isFinite) {
973+
return (this.isNegative ? "-" : "") + "Infinity";
974+
}
975+
976+
let s = this.abs().emitDecimal({
977+
normalize: false,
978+
numDecimalDigits: undefined,
979+
format: "decimal",
980+
});
981+
982+
let [lhs, rhs] = s.split(/[.]/);
983+
let p = this.isNegative ? "-" : "";
984+
985+
if (n <= lhs.length) {
986+
if (lhs.match(/[.]$/)) {
987+
lhs = lhs.substring(0, n);
988+
}
989+
990+
if (lhs.length === n) {
991+
return p + lhs;
992+
}
993+
994+
if (1 === n) {
995+
return p + s.substring(0, 1) + "e+" + `${lhs.length - n}`;
996+
}
997+
998+
return (
999+
p +
1000+
s.substring(0, 1) +
1001+
"." +
1002+
s.substring(1, n) +
1003+
"e+" +
1004+
`${lhs.length - n + 1}`
1005+
);
1006+
}
1007+
1008+
if (n <= lhs.length + rhs.length) {
1009+
return p + s.substring(0, n + 1); // plus one because of the decimal point
1010+
}
1011+
1012+
return p + lhs + "." + rhs + "0".repeat(n - lhs.length - rhs.length);
9551013
}
9561014

9571015
toExponential(): string {

tests/tofixed.test.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ describe("to decimal places", function () {
3636
test("same number of digits as available means no change", () => {
3737
expectDecimal128(decimalD.toFixed(3), "123.456");
3838
});
39-
test("cutoff if number has more digits than requested (1)", () => {
40-
expectDecimal128(decimalD.toFixed(2), "123.45");
39+
test("cutoff with rounding if number has more digits than requested (1)", () => {
40+
expectDecimal128(decimalD.toFixed(2), "123.46");
4141
});
42-
test("cutoff if number has more digits than requested (2)", () => {
42+
test("cutoff if number has more digits than requested (no rounding)", () => {
4343
expectDecimal128(decimalD.toFixed(1), "123.4");
4444
});
4545
test("zero decimal places", () => {

tests/toprecison.test.js

+40-18
Original file line numberDiff line numberDiff line change
@@ -29,35 +29,57 @@ describe("infinity", () => {
2929
});
3030
});
3131

32-
describe("to decimal places", function () {
32+
describe("toprecision", function () {
3333
const d = "123.456";
3434
const decimalD = new Decimal128(d);
35-
test("more digits than available means digits get added", () => {
36-
expectDecimal128(
37-
decimalD.toString({ numDecimalDigits: 4 }),
38-
"123.4560"
39-
);
35+
test("no argument", () => {
36+
expect(decimalD.toPrecision()).toStrictEqual("123.456");
37+
});
38+
test("wrong argument type", () => {
39+
expect(decimalD.toPrecision("foo")).toStrictEqual("123.456");
40+
});
41+
test("empty options", () => {
42+
expect(decimalD.toPrecision({})).toStrictEqual("123.456");
43+
});
44+
test("expected property missing", () => {
45+
expect(decimalD.toPrecision({ foo: "bar" })).toStrictEqual("123.456");
46+
});
47+
test("more digits requested than integer digits available", () => {
48+
expectDecimal128(decimalD.toPrecision({ digits: 7 }), "123.4560");
49+
});
50+
test("exact number of digits requested as digits available", () => {
51+
expectDecimal128(decimalD.toPrecision({ digits: 6 }), "123.456");
52+
});
53+
test("possibly round non-integer part (1)", () => {
54+
expectDecimal128(decimalD.toPrecision({ digits: 5 }), "123.45");
55+
});
56+
test("possibly round non-integer part (2)", () => {
57+
expectDecimal128(decimalD.toPrecision({ digits: 4 }), "123.4");
4058
});
4159
test("same number of digits as available means no change", () => {
42-
expectDecimal128(decimalD.toString({ numDecimalDigits: 3 }), "123.456");
60+
expectDecimal128(decimalD.toPrecision({ digits: 3 }), "123");
4361
});
4462
test("cutoff if number has more digits than requested (1)", () => {
45-
expectDecimal128(decimalD.toString({ numDecimalDigits: 2 }), "123.45");
63+
expectDecimal128(decimalD.toPrecision({ digits: 2 }), "1.2e+2");
4664
});
4765
test("cutoff if number has more digits than requested (2)", () => {
48-
expectDecimal128(decimalD.toString({ numDecimalDigits: 1 }), "123.4");
66+
expectDecimal128(decimalD.toPrecision({ digits: 1 }), "1e+2");
4967
});
50-
test("zero decimal places", () => {
51-
expectDecimal128(decimalD.toString({ numDecimalDigits: 0 }), "123");
68+
test("zero decimal places throws", () => {
69+
expect(() => decimalD.toPrecision({ digits: 0 })).toThrow(RangeError);
5270
});
5371
test("negative number of decimal places", () => {
54-
expect(decimalD.toString({ numDecimalDigits: -1 })).toStrictEqual(
55-
"123.456"
56-
);
72+
expect(() => decimalD.toPrecision({ digits: -1 })).toThrow(RangeError);
5773
});
58-
test("non-integer number of decimal places reverts to default", () => {
59-
expect(decimalD.toString({ numDecimalDigits: 1.5 })).toStrictEqual(
60-
"123.456"
61-
);
74+
test("non-integer number throws", () => {
75+
expect(() => decimalD.toPrecision({ digits: 1.5 })).toThrow(RangeError);
76+
});
77+
describe("negative", () => {
78+
let negD = decimalD.neg();
79+
test("integer part", () => {
80+
expect(negD.toPrecision({ digits: 3 }).toString()).toStrictEqual(
81+
"-123"
82+
);
83+
});
6284
});
6385
});

0 commit comments

Comments
 (0)