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

Commit 9d4e84b

Browse files
committed
Add tests for toExponential
1 parent 378f8f6 commit 9d4e84b

8 files changed

+196
-55
lines changed

src/decimal128.mts

+55-5
Original file line numberDiff line numberDiff line change
@@ -836,15 +836,15 @@ export class Decimal128 {
836836
let adjustedExponent = exp + sg.length - 1;
837837

838838
if (sg.length === 1) {
839-
return prefix + sg + "E" + (exp < 0 ? "" : "+") + exp;
839+
return prefix + sg + "e" + (exp < 0 ? "" : "+") + exp;
840840
}
841841

842842
return (
843843
prefix +
844844
sg.substring(0, 1) +
845845
"." +
846846
sg.substring(1) +
847-
"E" +
847+
"e" +
848848
(adjustedExponent < 0 ? "" : "+") +
849849
adjustedExponent
850850
);
@@ -951,7 +951,15 @@ export class Decimal128 {
951951
}
952952

953953
toPrecision(opts?: { digits?: number }): string {
954-
if (undefined === opts || undefined === opts.digits) {
954+
if (undefined === opts) {
955+
return this.toString();
956+
}
957+
958+
if ("object" !== typeof opts) {
959+
throw new TypeError("Argument must be an object");
960+
}
961+
962+
if (undefined === opts.digits) {
955963
return this.toString();
956964
}
957965

@@ -1012,8 +1020,50 @@ export class Decimal128 {
10121020
return p + lhs + "." + rhs + "0".repeat(n - lhs.length - rhs.length);
10131021
}
10141022

1015-
toExponential(): string {
1016-
return "7";
1023+
toExponential(opts?: { digits?: number }): string {
1024+
if (this.isNaN) {
1025+
return "NaN";
1026+
}
1027+
1028+
if (!this.isFinite) {
1029+
return (this.isNegative ? "-" : "") + "Infinity";
1030+
}
1031+
1032+
if (undefined === opts) {
1033+
return this.emitExponential();
1034+
}
1035+
1036+
if ("object" !== typeof opts) {
1037+
throw new TypeError("Argument must be an object");
1038+
}
1039+
1040+
if (undefined === opts.digits) {
1041+
return this.emitExponential();
1042+
}
1043+
1044+
let n = opts.digits;
1045+
1046+
if (n <= 0) {
1047+
throw new RangeError("Argument must be positive");
1048+
}
1049+
1050+
if (!Number.isInteger(n)) {
1051+
throw new RangeError("Argument must be an integer");
1052+
}
1053+
1054+
let s = this.abs().emitExponential();
1055+
1056+
let [lhs, rhsWithEsign] = s.split(/[.]/);
1057+
1058+
let [rhs, exp] = rhsWithEsign.split(/[eE]/);
1059+
1060+
let p = this.isNegative ? "-" : "";
1061+
1062+
if (rhs.length <= n) {
1063+
return p + lhs + "." + rhs + "0".repeat(n - rhs.length) + "e" + exp;
1064+
}
1065+
1066+
return p + lhs + "." + rhs.substring(0, n) + "e" + exp;
10171067
}
10181068

10191069
private isInteger(): boolean {

tests/add.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,6 @@ describe("examples from the General Decimal Arithmetic specification", () => {
138138
new Decimal128("1E+2")
139139
.add(new Decimal128("1E+4"))
140140
.toString({ format: "exponential" })
141-
).toStrictEqual("1.01E+4");
141+
).toStrictEqual("1.01e+4");
142142
});
143143
});

tests/constructor.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ describe("General Decimal Arithmetic specification", () => {
577577
test("0E+2", () => {
578578
expect(
579579
new Decimal128("0E+2").toString({ format: "exponential" })
580-
).toStrictEqual("0E+2");
580+
).toStrictEqual("0e+2");
581581
});
582582
});
583583
});

tests/divide.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,6 @@ describe("examples from the General Decimal Arithmetic Specification", () => {
189189
new Decimal128("2.40E+6")
190190
.divide(new Decimal128("2"))
191191
.toString({ format: "exponential" })
192-
).toStrictEqual("1.20E+6");
192+
).toStrictEqual("1.20e+6");
193193
});
194194
});

tests/multiply.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,6 @@ describe("examples from the General Decimal Arithmetic specification", () => {
192192
new Decimal128("654321")
193193
.multiply(new Decimal128("654321"))
194194
.toString({ format: "exponential" })
195-
).toStrictEqual("4.28135971041E+11");
195+
).toStrictEqual("4.28135971041e+11");
196196
});
197197
});

tests/toexponential.test.js

+136
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
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").toExponential()).toStrictEqual("NaN");
7+
});
8+
});
9+
10+
describe("zero", () => {
11+
test("positive zero", () => {
12+
expect(new Decimal128("0").toExponential()).toStrictEqual("0e+0");
13+
});
14+
test("negative zero", () => {
15+
expect(new Decimal128("-0").toExponential()).toStrictEqual("-0e+0");
16+
});
17+
});
18+
19+
describe("infinity", () => {
20+
test("positive infinity", () => {
21+
expect(new Decimal128("Infinity").toExponential()).toStrictEqual(
22+
"Infinity"
23+
);
24+
});
25+
test("negative infinity", () => {
26+
expect(new Decimal128("-Infinity").toExponential()).toStrictEqual(
27+
"-Infinity"
28+
);
29+
});
30+
});
31+
32+
describe("toExponential", function () {
33+
const d = "123.456";
34+
const decimalD = new Decimal128(d);
35+
test("no argument", () => {
36+
expect(decimalD.toExponential()).toStrictEqual("1.23456e+2");
37+
});
38+
test("wrong argument type", () => {
39+
expect(() => decimalD.toExponential("foo")).toThrow(TypeError);
40+
});
41+
test("empty options", () => {
42+
expect(decimalD.toExponential({})).toStrictEqual("1.23456e+2");
43+
});
44+
test("expected property missing", () => {
45+
expect(decimalD.toExponential({ foo: "bar" })).toStrictEqual(
46+
"1.23456e+2"
47+
);
48+
});
49+
test("more digits requested than integer digits available", () => {
50+
expectDecimal128(decimalD.toExponential({ digits: 7 }), "1.2345600e+2");
51+
});
52+
test("exact number of digits requested as digits available", () => {
53+
expectDecimal128(decimalD.toExponential({ digits: 6 }), "1.234560e+2");
54+
});
55+
test("possibly round non-integer part (1)", () => {
56+
expectDecimal128(decimalD.toExponential({ digits: 5 }), "1.23456e+2");
57+
});
58+
test("possibly round non-integer part (2)", () => {
59+
expectDecimal128(decimalD.toExponential({ digits: 4 }), "1.2345e+2");
60+
});
61+
test("same number of digits as available means no change", () => {
62+
expectDecimal128(decimalD.toExponential({ digits: 3 }), "1.234e+2");
63+
});
64+
test("cutoff if number has more digits than requested (1)", () => {
65+
expectDecimal128(decimalD.toExponential({ digits: 2 }), "1.23e+2");
66+
});
67+
test("cutoff if number has more digits than requested (2)", () => {
68+
expectDecimal128(decimalD.toExponential({ digits: 1 }), "1.2e+2");
69+
});
70+
test("zero decimal places throws", () => {
71+
expect(() => decimalD.toExponential({ digits: 0 })).toThrow(RangeError);
72+
});
73+
test("negative number of decimal places", () => {
74+
expect(() => decimalD.toExponential({ digits: -1 })).toThrow(
75+
RangeError
76+
);
77+
});
78+
test("non-integer number throws", () => {
79+
expect(() => decimalD.toExponential({ digits: 1.5 })).toThrow(
80+
RangeError
81+
);
82+
});
83+
describe("negative", () => {
84+
let negD = decimalD.neg();
85+
test("integer part", () => {
86+
expect(negD.toExponential({ digits: 3 }).toString()).toStrictEqual(
87+
"-1.234e+2"
88+
);
89+
});
90+
});
91+
});
92+
93+
describe("to exponential string", () => {
94+
test("one", () => {
95+
expect(
96+
new Decimal128("1").toString({ format: "exponential" })
97+
).toStrictEqual("1e+0");
98+
});
99+
test("zero", () => {
100+
expect(
101+
new Decimal128("0").toString({ format: "exponential" })
102+
).toStrictEqual("0e+0");
103+
});
104+
test("minus zero", () => {
105+
expect(
106+
new Decimal128("-0").toString({ format: "exponential" })
107+
).toStrictEqual("-0e+0");
108+
});
109+
test("integer", () => {
110+
expect(
111+
new Decimal128("42").toString({ format: "exponential" })
112+
).toStrictEqual("4.2e+1");
113+
});
114+
115+
test("round trip", () => {
116+
expect(
117+
new Decimal128("4.2E+0").toString({ format: "exponential" })
118+
).toStrictEqual("4.2e+0");
119+
});
120+
121+
test("significant has one digit", () => {
122+
expect(
123+
new Decimal128("1").toString({ format: "exponential" })
124+
).toStrictEqual("1e+0");
125+
});
126+
test("negative exponent", () => {
127+
expect(
128+
new Decimal128("0.1").toString({ format: "exponential" })
129+
).toStrictEqual("1e-1");
130+
});
131+
test("negative exponent, multiple digits", () => {
132+
expect(
133+
new Decimal128("0.01042").toString({ format: "exponential" })
134+
).toStrictEqual("1.042e-2");
135+
});
136+
});

tests/toprecison.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ describe("toprecision", function () {
3636
expect(decimalD.toPrecision()).toStrictEqual("123.456");
3737
});
3838
test("wrong argument type", () => {
39-
expect(decimalD.toPrecision("foo")).toStrictEqual("123.456");
39+
expect(() => decimalD.toPrecision("foo")).toThrow(TypeError);
4040
});
4141
test("empty options", () => {
4242
expect(decimalD.toPrecision({})).toStrictEqual("123.456");

tests/tostring.test.js

-45
Original file line numberDiff line numberDiff line change
@@ -60,51 +60,6 @@ describe("to decimal places", function () {
6060
});
6161
});
6262

63-
describe("to exponential string", () => {
64-
test("one", () => {
65-
expect(
66-
new Decimal128("1").toString({ format: "exponential" })
67-
).toStrictEqual("1E+0");
68-
});
69-
test("zero", () => {
70-
expect(
71-
new Decimal128("0").toString({ format: "exponential" })
72-
).toStrictEqual("0E+0");
73-
});
74-
test("minus zero", () => {
75-
expect(
76-
new Decimal128("-0").toString({ format: "exponential" })
77-
).toStrictEqual("-0E+0");
78-
});
79-
test("integer", () => {
80-
expect(
81-
new Decimal128("42").toString({ format: "exponential" })
82-
).toStrictEqual("4.2E+1");
83-
});
84-
85-
test("round trip", () => {
86-
expect(
87-
new Decimal128("4.2E+0").toString({ format: "exponential" })
88-
).toStrictEqual("4.2E+0");
89-
});
90-
91-
test("significant has one digit", () => {
92-
expect(
93-
new Decimal128("1").toString({ format: "exponential" })
94-
).toStrictEqual("1E+0");
95-
});
96-
test("negative exponent", () => {
97-
expect(
98-
new Decimal128("0.1").toString({ format: "exponential" })
99-
).toStrictEqual("1E-1");
100-
});
101-
test("negative exponent, multiple digits", () => {
102-
expect(
103-
new Decimal128("0.01042").toString({ format: "exponential" })
104-
).toStrictEqual("1.042E-2");
105-
});
106-
});
107-
10863
describe("normalization", () => {
10964
test("on by default", () => {
11065
expect(new Decimal128("1.20").toString()).toStrictEqual("1.2");

0 commit comments

Comments
 (0)