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

Commit 5104b9e

Browse files
committed
Improve coverage
1 parent 178d876 commit 5104b9e

File tree

3 files changed

+29
-191
lines changed

3 files changed

+29
-191
lines changed

src/Decimal.mts

+9-138
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,7 @@ function _cohort(s: string): "0" | "-0" | Rational {
1111
return "-0";
1212
}
1313

14-
if (c === "-0") {
15-
return "0";
16-
}
17-
18-
return c.negate();
14+
return (c as Rational).negate();
1915
}
2016

2117
if (s.match(/^00+/)) {
@@ -26,11 +22,7 @@ function _cohort(s: string): "0" | "-0" | Rational {
2622
return "0";
2723
}
2824

29-
if (s.match(/^-?0[eE][+-]?[0-9]+$/)) {
30-
if (s.match(/^-/)) {
31-
return "-0";
32-
}
33-
25+
if (s.match(/^0[eE][+-]?[0-9]+$/)) {
3426
return "0";
3527
}
3628

@@ -79,7 +71,11 @@ export class Decimal {
7971
}
8072

8173
if (!Number.isInteger(q)) {
82-
throw new Error("The quantum must be an integer.");
74+
throw new RangeError("The quantum must be an integer.");
75+
}
76+
77+
if (Object.is(q, -0)) {
78+
throw new RangeError("The quantum cannot be negative zero.");
8379
}
8480

8581
if (v instanceof Rational) {
@@ -96,144 +92,19 @@ export class Decimal {
9692
this.quantum = q;
9793
}
9894

99-
public isZero(): boolean {
100-
let v = this.cohort;
101-
return v === "0" || v === "-0";
102-
}
103-
104-
public isInteger(): boolean {
105-
let v = this.cohort;
106-
107-
if (v === "0" || v === "-0") {
108-
return true;
109-
}
110-
111-
return v.isInteger();
112-
}
113-
114-
public isNegative(): boolean {
115-
let v = this.cohort;
116-
117-
if (v === "0") {
118-
return false;
119-
}
120-
121-
if (v === "-0") {
122-
return true;
123-
}
124-
125-
return v.isNegative;
126-
}
127-
128-
public scale10(n: number, adjustQuantum?: boolean): Decimal {
129-
if (!Number.isInteger(n)) {
130-
throw new Error("The scale factor must be an integer.");
131-
}
132-
133-
if (0 === n) {
134-
return this;
135-
}
136-
137-
let v = this.cohort;
138-
let newQuantum = this.quantum;
139-
140-
if (typeof adjustQuantum === "boolean" && adjustQuantum) {
141-
if (n < 0) {
142-
newQuantum -= n;
143-
} else {
144-
newQuantum += n;
145-
}
146-
}
147-
148-
if (v === "0" || v === "-0") {
149-
return new Decimal({ cohort: v, quantum: newQuantum });
150-
}
151-
152-
return new Decimal({
153-
cohort: v.scale10(n),
154-
quantum: newQuantum,
155-
});
156-
}
157-
15895
public negate(): Decimal {
159-
let v = this.cohort;
160-
161-
if (v === "0") {
162-
return new Decimal({ cohort: "-0", quantum: this.quantum });
163-
}
164-
165-
if (v === "-0") {
166-
return new Decimal({ cohort: "0", quantum: this.quantum });
167-
}
96+
let v = this.cohort as Rational;
16897

16998
return new Decimal({
17099
cohort: v.negate(),
171100
quantum: this.quantum,
172101
});
173102
}
174103

175-
public significand(): Rational {
176-
if (this.isNegative()) {
177-
return this.negate().significand();
178-
}
179-
180-
let v = this.cohort;
181-
182-
if (v === "0" || v === "-0") {
183-
throw new RangeError("Cannot compute coefficient of zero.");
184-
}
185-
186-
while (ratTen.lessThan(v) || ratTen.equals(v)) {
187-
v = v.scale10(-1);
188-
}
189-
190-
while (v.lessThan(ratOne)) {
191-
v = v.scale10(1);
192-
}
193-
194-
return v;
195-
}
196-
197-
public exponent(): number {
198-
if (this.isNegative()) {
199-
return this.negate().exponent();
200-
}
201-
202-
let v = this.cohort;
203-
204-
if (v === "0" || v === "-0") {
205-
throw new RangeError("Cannot compute coefficient of zero.");
206-
}
207-
208-
let e = 0;
209-
210-
while (ratTen.lessThan(v) || ratTen.equals(v)) {
211-
v = v.scale10(-1);
212-
e++;
213-
}
214-
215-
while (v.lessThan(ratOne)) {
216-
v = v.scale10(1);
217-
e--;
218-
}
219-
220-
return e;
221-
}
222-
223104
public coefficient(): bigint {
224-
let v = this.cohort;
225-
226-
if (v === "0" || v === "-0") {
227-
throw new RangeError("Cannot compute coefficient of zero.");
228-
}
229-
105+
let v = this.cohort as Rational;
230106
let q = this.quantum;
231107
let c = v.scale10(0 - q);
232-
233-
if (!c.isInteger()) {
234-
throw new TypeError("The coefficient is not an integer.");
235-
}
236-
237108
return c.numerator;
238109
}
239110
}

src/common.mts

-53
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ export function countFractionalDigits(s: string): number {
4040
}
4141

4242
export type Digit = -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9; // -1 signals that we're moving from the integer part to the decimal part of a decimal number
43-
export type DigitOrTen = Digit | 10;
4443

4544
export const ROUNDING_MODE_CEILING = "ceil";
4645
export const ROUNDING_MODE_FLOOR = "floor";
@@ -62,55 +61,3 @@ export const ROUNDING_MODES: RoundingMode[] = [
6261
ROUNDING_MODE_HALF_EVEN,
6362
ROUNDING_MODE_HALF_EXPAND,
6463
];
65-
66-
function roundIt(
67-
isNegative: boolean,
68-
digitToRound: Digit,
69-
decidingDigit: Digit,
70-
roundingMode: RoundingMode
71-
): DigitOrTen {
72-
switch (roundingMode) {
73-
case ROUNDING_MODE_CEILING:
74-
if (isNegative) {
75-
return digitToRound;
76-
}
77-
78-
if (0 === decidingDigit) {
79-
return digitToRound;
80-
}
81-
82-
return (digitToRound + 1) as DigitOrTen;
83-
case ROUNDING_MODE_FLOOR:
84-
if (0 === decidingDigit) {
85-
return digitToRound;
86-
}
87-
88-
if (isNegative) {
89-
return (digitToRound + 1) as DigitOrTen;
90-
}
91-
92-
return digitToRound;
93-
case ROUNDING_MODE_TRUNCATE:
94-
return digitToRound;
95-
case ROUNDING_MODE_HALF_EXPAND:
96-
if (decidingDigit >= 5) {
97-
return (digitToRound + 1) as DigitOrTen;
98-
}
99-
100-
return digitToRound;
101-
default: // ROUNDING_MODE_HALF_EVEN:
102-
if (decidingDigit === 5) {
103-
if (digitToRound % 2 === 0) {
104-
return digitToRound;
105-
}
106-
107-
return (digitToRound + 1) as DigitOrTen;
108-
}
109-
110-
if (decidingDigit > 5) {
111-
return (digitToRound + 1) as DigitOrTen;
112-
}
113-
114-
return digitToRound;
115-
}
116-
}

tests/Decimal/constructor.test.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { Decimal } from "../../src/Decimal.mjs";
2+
import { Rational } from "../../src/Rational.mjs";
3+
4+
describe("Decimal constructor", () => {
5+
test("fails if given zero", () => {
6+
expect(
7+
() => new Decimal({ cohort: new Rational(0n, 1n), quantum: 0 })
8+
).toThrow(RangeError);
9+
});
10+
test("fails if quantum is a non-integer", () => {
11+
expect(
12+
() => new Decimal({ cohort: new Rational(1n, 1n), quantum: 1.5 })
13+
).toThrow(RangeError);
14+
});
15+
test("fails if quantum is minus zero", () => {
16+
expect(
17+
() => new Decimal({ cohort: new Rational(1n, 1n), quantum: -0 })
18+
).toThrow(RangeError);
19+
});
20+
});

0 commit comments

Comments
 (0)