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

Commit

Permalink
Add tests for toPrecision
Browse files Browse the repository at this point in the history
  • Loading branch information
jessealama committed Jun 19, 2024
1 parent 07ec1f1 commit 378f8f6
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 23 deletions.
62 changes: 60 additions & 2 deletions src/decimal128.mts
Original file line number Diff line number Diff line change
Expand Up @@ -950,8 +950,66 @@ export class Decimal128 {
return this.round(n).emitDecimal(opts);
}

toPrecision(n?: number): string {
return "6";
toPrecision(opts?: { digits?: number }): string {
if (undefined === opts || undefined === opts.digits) {
return this.toString();
}

let n = opts.digits;

if (n <= 0) {
throw new RangeError("Argument must be positive");
}

if (!Number.isInteger(n)) {
throw new RangeError("Argument must be an integer");
}

if (this.isNaN) {
return "NaN";
}

if (!this.isFinite) {
return (this.isNegative ? "-" : "") + "Infinity";
}

let s = this.abs().emitDecimal({
normalize: false,
numDecimalDigits: undefined,
format: "decimal",
});

let [lhs, rhs] = s.split(/[.]/);
let p = this.isNegative ? "-" : "";

if (n <= lhs.length) {
if (lhs.match(/[.]$/)) {
lhs = lhs.substring(0, n);
}

if (lhs.length === n) {
return p + lhs;
}

if (1 === n) {
return p + s.substring(0, 1) + "e+" + `${lhs.length - n}`;
}

return (
p +
s.substring(0, 1) +
"." +
s.substring(1, n) +
"e+" +
`${lhs.length - n + 1}`
);
}

if (n <= lhs.length + rhs.length) {
return p + s.substring(0, n + 1); // plus one because of the decimal point
}

return p + lhs + "." + rhs + "0".repeat(n - lhs.length - rhs.length);
}

toExponential(): string {
Expand Down
6 changes: 3 additions & 3 deletions tests/tofixed.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ describe("to decimal places", function () {
test("same number of digits as available means no change", () => {
expectDecimal128(decimalD.toFixed(3), "123.456");
});
test("cutoff if number has more digits than requested (1)", () => {
expectDecimal128(decimalD.toFixed(2), "123.45");
test("cutoff with rounding if number has more digits than requested (1)", () => {
expectDecimal128(decimalD.toFixed(2), "123.46");
});
test("cutoff if number has more digits than requested (2)", () => {
test("cutoff if number has more digits than requested (no rounding)", () => {
expectDecimal128(decimalD.toFixed(1), "123.4");
});
test("zero decimal places", () => {
Expand Down
58 changes: 40 additions & 18 deletions tests/toprecison.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,35 +29,57 @@ describe("infinity", () => {
});
});

describe("to decimal places", function () {
describe("toprecision", function () {
const d = "123.456";
const decimalD = new Decimal128(d);
test("more digits than available means digits get added", () => {
expectDecimal128(
decimalD.toString({ numDecimalDigits: 4 }),
"123.4560"
);
test("no argument", () => {
expect(decimalD.toPrecision()).toStrictEqual("123.456");
});
test("wrong argument type", () => {
expect(decimalD.toPrecision("foo")).toStrictEqual("123.456");
});
test("empty options", () => {
expect(decimalD.toPrecision({})).toStrictEqual("123.456");
});
test("expected property missing", () => {
expect(decimalD.toPrecision({ foo: "bar" })).toStrictEqual("123.456");
});
test("more digits requested than integer digits available", () => {
expectDecimal128(decimalD.toPrecision({ digits: 7 }), "123.4560");
});
test("exact number of digits requested as digits available", () => {
expectDecimal128(decimalD.toPrecision({ digits: 6 }), "123.456");
});
test("possibly round non-integer part (1)", () => {
expectDecimal128(decimalD.toPrecision({ digits: 5 }), "123.45");
});
test("possibly round non-integer part (2)", () => {
expectDecimal128(decimalD.toPrecision({ digits: 4 }), "123.4");
});
test("same number of digits as available means no change", () => {
expectDecimal128(decimalD.toString({ numDecimalDigits: 3 }), "123.456");
expectDecimal128(decimalD.toPrecision({ digits: 3 }), "123");
});
test("cutoff if number has more digits than requested (1)", () => {
expectDecimal128(decimalD.toString({ numDecimalDigits: 2 }), "123.45");
expectDecimal128(decimalD.toPrecision({ digits: 2 }), "1.2e+2");
});
test("cutoff if number has more digits than requested (2)", () => {
expectDecimal128(decimalD.toString({ numDecimalDigits: 1 }), "123.4");
expectDecimal128(decimalD.toPrecision({ digits: 1 }), "1e+2");
});
test("zero decimal places", () => {
expectDecimal128(decimalD.toString({ numDecimalDigits: 0 }), "123");
test("zero decimal places throws", () => {
expect(() => decimalD.toPrecision({ digits: 0 })).toThrow(RangeError);
});
test("negative number of decimal places", () => {
expect(decimalD.toString({ numDecimalDigits: -1 })).toStrictEqual(
"123.456"
);
expect(() => decimalD.toPrecision({ digits: -1 })).toThrow(RangeError);
});
test("non-integer number of decimal places reverts to default", () => {
expect(decimalD.toString({ numDecimalDigits: 1.5 })).toStrictEqual(
"123.456"
);
test("non-integer number throws", () => {
expect(() => decimalD.toPrecision({ digits: 1.5 })).toThrow(RangeError);
});
describe("negative", () => {
let negD = decimalD.neg();
test("integer part", () => {
expect(negD.toPrecision({ digits: 3 }).toString()).toStrictEqual(
"-123"
);
});
});
});

0 comments on commit 378f8f6

Please sign in to comment.