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

Commit 569e881

Browse files
committed
WIP
1 parent 4f5ee87 commit 569e881

File tree

5 files changed

+208
-536
lines changed

5 files changed

+208
-536
lines changed

src/Decimal128.mts

+10-10
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* @author Jesse Alama <[email protected]>
1414
*/
1515

16-
import { Digit, DigitOrTen, RoundingMode, ROUNDING_MODES } from "./common.mjs";
16+
import { RoundingMode, ROUNDING_MODES } from "./common.mjs";
1717
import { Rational } from "./Rational.mjs";
1818
import { Decimal } from "./Decimal.mjs";
1919

@@ -596,7 +596,7 @@ export class Decimal128 {
596596
*
597597
* @param x
598598
*/
599-
private cmp(x: Decimal128): number {
599+
cmp(x: Decimal128): number {
600600
if (this.isNaN() || x.isNaN()) {
601601
return NaN;
602602
}
@@ -621,20 +621,20 @@ export class Decimal128 {
621621
return x.isNegative() ? 1 : -1;
622622
}
623623

624+
if (this.isZero()) {
625+
if (x.isZero()) {
626+
return 0;
627+
}
628+
629+
return x.isNegative() ? 1 : -1;
630+
}
631+
624632
let ourCohort = this.cohort() as Rational;
625633
let theirCohort = x.cohort() as Rational;
626634

627635
return ourCohort.cmp(theirCohort);
628636
}
629637

630-
lessThan(x: Decimal128): boolean {
631-
return this.cmp(x) === -1;
632-
}
633-
634-
equals(x: Decimal128): boolean {
635-
return this.cmp(x) === 0;
636-
}
637-
638638
abs(): Decimal128 {
639639
if (this.isNaN()) {
640640
return new Decimal128(NAN);

tests/Decimal128/abs.test.js

-6
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,6 @@ import { Decimal128 } from "../../src/Decimal128.mjs";
33
const MAX_SIGNIFICANT_DIGITS = 34;
44
const bigDigits = "9".repeat(MAX_SIGNIFICANT_DIGITS);
55

6-
const zero = new Decimal128("0");
7-
const minusZero = new Decimal128("-0");
8-
const one = new Decimal128("1");
9-
const minusOne = new Decimal128("-1");
10-
const two = new Decimal128("2");
11-
126
describe("abs", () => {
137
test("minus zero", () => {
148
expect(new Decimal128("-0").abs().toString()).toStrictEqual("0");

tests/Decimal128/cmp.test.js

+198
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
import { Decimal128 } from "../../src/Decimal128.mjs";
2+
3+
const MAX_SIGNIFICANT_DIGITS = 34;
4+
const nan = new Decimal128("NaN");
5+
const zero = new Decimal128("0");
6+
const negZero = new Decimal128("-0");
7+
const one = new Decimal128("1");
8+
9+
describe("equals", () => {
10+
let d1 = new Decimal128("987.123");
11+
let d2 = new Decimal128("123.456789");
12+
test("simple example", () => {
13+
expect(d1.cmp(d1)).toStrictEqual(0);
14+
});
15+
test("non-example", () => {
16+
expect(d1.cmp(d2)).toStrictEqual(1);
17+
});
18+
test("negative numbers", () => {
19+
let a = new Decimal128("-123.456");
20+
expect(a.cmp(a)).toStrictEqual(0);
21+
});
22+
test("integer part is the same, decimal part is not", () => {
23+
let a = new Decimal128("42.678");
24+
let b = new Decimal128("42.6789");
25+
expect(a.cmp(b)).toStrictEqual(-1);
26+
});
27+
test("negative and positive are different", () => {
28+
expect(
29+
new Decimal128("-123.456").cmp(new Decimal128("123.456"))
30+
).toStrictEqual(-1);
31+
});
32+
test("limit of significant digits", () => {
33+
expect(
34+
new Decimal128("0.4166666666666666666666666666666667").cmp(
35+
new Decimal128("0.41666666666666666666666666666666666")
36+
)
37+
).toStrictEqual(0);
38+
});
39+
test("beyond limit of significant digits", () => {
40+
expect(
41+
new Decimal128("0.41666666666666666666666666666666667").cmp(
42+
new Decimal128("0.41666666666666666666666666666666666")
43+
)
44+
).toStrictEqual(0);
45+
});
46+
test("non-example", () => {
47+
expect(
48+
new Decimal128("0.037").cmp(new Decimal128("0.037037037037"))
49+
).toStrictEqual(-1);
50+
});
51+
describe("examples from a presentation", () => {
52+
let a = new Decimal128("1.00");
53+
let b = new Decimal128("1.0000");
54+
let c = new Decimal128("1.0001");
55+
let d = new Decimal128("0.9999");
56+
test("use mathematical equality by default", () => {
57+
expect(a.cmp(b)).toStrictEqual(0);
58+
});
59+
test("mathematically distinct", () => {
60+
expect(a.cmp(c)).toStrictEqual(-1);
61+
});
62+
test("mathematically distinct, again", () => {
63+
expect(b.cmp(d)).toStrictEqual(1);
64+
});
65+
test("mathematically distinct, once more", () => {
66+
expect(a.cmp(d)).toStrictEqual(1);
67+
});
68+
});
69+
});
70+
71+
describe("many digits", () => {
72+
test("non-integers get rounded", () => {
73+
expect(
74+
new Decimal128("0." + "4".repeat(MAX_SIGNIFICANT_DIGITS + 50)).cmp(
75+
new Decimal128("0." + "4".repeat(MAX_SIGNIFICANT_DIGITS))
76+
)
77+
).toStrictEqual(0);
78+
});
79+
test("non-equality within limits", () => {
80+
expect(
81+
new Decimal128("0." + "4".repeat(33)).cmp(
82+
new Decimal128("0." + "4".repeat(MAX_SIGNIFICANT_DIGITS))
83+
)
84+
).toStrictEqual(-1);
85+
});
86+
describe("NaN", () => {
87+
test("NaN equals NaN throws", () => {
88+
expect(nan.cmp(nan)).toStrictEqual(NaN);
89+
});
90+
test("number equals NaN throws", () => {
91+
expect(one.cmp(nan)).toStrictEqual(NaN);
92+
});
93+
test("NaN equals number throws", () => {
94+
expect(nan.cmp(one)).toStrictEqual(NaN);
95+
});
96+
});
97+
describe("minus zero", () => {
98+
test("left hand", () => {
99+
expect(negZero.cmp(zero)).toStrictEqual(0);
100+
});
101+
test("right hand", () => {
102+
expect(zero.cmp(negZero)).toStrictEqual(0);
103+
});
104+
test("both arguments", () => {
105+
expect(negZero.cmp(negZero)).toStrictEqual(0);
106+
});
107+
});
108+
describe("infinity", () => {
109+
let posInf = new Decimal128("Infinity");
110+
let negInf = new Decimal128("-Infinity");
111+
test("positive infinity vs number", () => {
112+
expect(posInf.cmp(one)).toStrictEqual(1);
113+
});
114+
test("negative infinity vs number", () => {
115+
expect(negInf.cmp(one)).toStrictEqual(-1);
116+
});
117+
test("negative infintity vs positive infinity", () => {
118+
expect(negInf.cmp(posInf)).toStrictEqual(-1);
119+
});
120+
test("positive infinity vs negative infinity", () => {
121+
expect(posInf.cmp(negInf)).toStrictEqual(1);
122+
});
123+
test("positive infinity both arguments", () => {
124+
expect(posInf.cmp(posInf)).toStrictEqual(0);
125+
});
126+
test("negative infinity both arguments", () => {
127+
expect(negInf.cmp(negInf)).toStrictEqual(0);
128+
});
129+
test("compare number to positive infinity", () => {
130+
expect(one.cmp(posInf)).toStrictEqual(-1);
131+
});
132+
test("compare number to negative infinity", () => {
133+
expect(one.cmp(negInf)).toStrictEqual(1);
134+
});
135+
});
136+
});
137+
138+
describe("zero", () => {
139+
test("positive zero", () => {
140+
expect(zero.cmp(zero)).toStrictEqual(0);
141+
});
142+
test("negative zero", () => {
143+
expect(negZero.cmp(negZero)).toStrictEqual(0);
144+
});
145+
test("negative zero vs zero", () => {
146+
expect(negZero.cmp(zero)).toStrictEqual(0);
147+
});
148+
});
149+
150+
describe("normalization", () => {
151+
let d1 = new Decimal128("1.2");
152+
let d2 = new Decimal128("1.20");
153+
let d3 = new Decimal128("1.200");
154+
test("compare normalized to normalized", () => {
155+
expect(d1.cmp(d2)).toStrictEqual(0);
156+
});
157+
test("compare normalized to normalized", () => {
158+
expect(d2.cmp(d3)).toStrictEqual(0);
159+
});
160+
test("compare normalized to normalized", () => {
161+
expect(d1.cmp(d3)).toStrictEqual(0);
162+
});
163+
});
164+
165+
describe("examples from the General Decimal Arithmetic specification", () => {
166+
describe("compare", () => {
167+
test("example one", () => {
168+
expect(
169+
new Decimal128("2.1").cmp(new Decimal128("3"))
170+
).toStrictEqual(-1);
171+
});
172+
test("example two", () => {
173+
expect(
174+
new Decimal128("2.1").cmp(new Decimal128("2.1"))
175+
).toStrictEqual(0);
176+
});
177+
test("example three", () => {
178+
expect(
179+
new Decimal128("2.1").cmp(new Decimal128("2.10"))
180+
).toStrictEqual(0);
181+
});
182+
test("example four", () => {
183+
expect(
184+
new Decimal128("3").cmp(new Decimal128("2.1"))
185+
).toStrictEqual(1);
186+
});
187+
test("example five", () => {
188+
expect(
189+
new Decimal128("2.1").cmp(new Decimal128("-3"))
190+
).toStrictEqual(1);
191+
});
192+
test("example six", () => {
193+
expect(
194+
new Decimal128("-3").cmp(new Decimal128("2.1"))
195+
).toStrictEqual(-1);
196+
});
197+
});
198+
});

0 commit comments

Comments
 (0)