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

Commit 7e314c4

Browse files
committed
WIP
1 parent 6e9ed93 commit 7e314c4

File tree

5 files changed

+102
-88
lines changed

5 files changed

+102
-88
lines changed

src/Decimal.mts

+8-3
Original file line numberDiff line numberDiff line change
@@ -213,9 +213,14 @@ export class Decimal {
213213
}
214214

215215
public coefficient(): bigint {
216-
let sig = this.significand();
217-
let exp = this.exponent();
218-
let c = sig.scale10(exp);
216+
let v = this.cohort;
217+
218+
if (v === "0" || v === "-0") {
219+
throw new RangeError("Cannot compute coefficient of zero.");
220+
}
221+
222+
let q = this.quantum;
223+
let c = v.scale10(0 - q);
219224

220225
if (!c.isInteger()) {
221226
throw new TypeError("The coefficient is not an integer.");

src/Decimal128.mts

+43-30
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,7 @@ function adjustDecimal128(v: Rational, q: number): Decimal {
5454

5555
let x = new Decimal({ cohort: v, quantum: q });
5656

57-
if (
58-
v
59-
.abs()
60-
.scale10(0 - q)
61-
.cmp(TEN_MAX_EXPONENT) <= 0
62-
) {
57+
if (v.scale10(0 - q).cmp(TEN_MAX_EXPONENT) <= 0) {
6358
return x;
6459
}
6560

@@ -76,6 +71,10 @@ function adjustDecimal128(v: Rational, q: number): Decimal {
7671
let cAsString = c.toFixed(Infinity);
7772
let [integerPart, fractionalPart] = cAsString.split(/[.]/);
7873

74+
if (integerPart === "0") {
75+
integerPart = "";
76+
}
77+
7978
if (integerPart.length > MAX_SIGNIFICANT_DIGITS) {
8079
throw new RangeError("Integer part too large");
8180
}
@@ -267,7 +266,7 @@ export class Decimal128 {
267266
}
268267

269268
if (this.isNegative()) {
270-
let [s, e] = this.neg().significandAndExponent();
269+
let [s, e] = this.negate().significandAndExponent();
271270
return [s.negate(), e];
272271
}
273272

@@ -302,7 +301,7 @@ export class Decimal128 {
302301
}
303302

304303
if (this.isNegative()) {
305-
return this.neg().mantissa().neg();
304+
return this.negate().mantissa().negate();
306305
}
307306

308307
let x: Decimal128 = this;
@@ -345,7 +344,7 @@ export class Decimal128 {
345344
);
346345
}
347346

348-
private significand(): bigint {
347+
private coefficient(): bigint {
349348
if (this.isZero()) {
350349
throw new RangeError("Zero does not have a significand");
351350
}
@@ -722,14 +721,14 @@ export class Decimal128 {
722721

723722
if (!this.isFinite()) {
724723
if (this.isNegative()) {
725-
return this.neg();
724+
return this.negate();
726725
}
727726

728727
return this.clone();
729728
}
730729

731730
if (this.isNegative()) {
732-
return this.neg();
731+
return this.negate();
733732
}
734733

735734
return this.clone();
@@ -762,7 +761,7 @@ export class Decimal128 {
762761
}
763762

764763
if (this.isNegative() && x.isNegative()) {
765-
return this.neg().add(x.neg()).neg();
764+
return this.negate().add(x.negate()).negate();
766765
}
767766

768767
if (this.isZero()) {
@@ -819,15 +818,15 @@ export class Decimal128 {
819818
}
820819

821820
if (!x.isFinite()) {
822-
return x.neg();
821+
return x.negate();
823822
}
824823

825824
if (x.isNegative()) {
826-
return this.add(x.neg());
825+
return this.add(x.negate());
827826
}
828827

829828
if (this.isZero()) {
830-
return x.neg();
829+
return x.negate();
831830
}
832831

833832
if (x.isZero()) {
@@ -897,11 +896,11 @@ export class Decimal128 {
897896
}
898897

899898
if (this.isNegative()) {
900-
return this.neg().multiply(x).neg();
899+
return this.negate().multiply(x).negate();
901900
}
902901

903902
if (x.isNegative()) {
904-
return this.multiply(x.neg()).neg();
903+
return this.multiply(x.negate()).negate();
905904
}
906905

907906
let ourCohort = this.cohort() as Rational;
@@ -940,7 +939,19 @@ export class Decimal128 {
940939
}
941940

942941
private clone(): Decimal128 {
943-
return new Decimal128(this.toString());
942+
if (this.isNaN()) {
943+
return new Decimal128(NAN);
944+
}
945+
946+
if (!this.isFinite()) {
947+
return new Decimal128(
948+
this.isNegative() ? NEGATIVE_INFINITY : POSITIVE_INFINITY
949+
);
950+
}
951+
952+
return new Decimal128(
953+
new Decimal({ cohort: this.cohort(), quantum: this.quantum() })
954+
);
944955
}
945956

946957
/**
@@ -953,14 +964,14 @@ export class Decimal128 {
953964
return new Decimal128(NAN);
954965
}
955966

956-
if (this.isZero()) {
957-
return this.clone();
958-
}
959-
960967
if (x.isZero()) {
961968
return new Decimal128(NAN);
962969
}
963970

971+
if (this.isZero()) {
972+
return this.clone();
973+
}
974+
964975
if (!this.isFinite()) {
965976
if (!x.isFinite()) {
966977
return new Decimal128(NAN);
@@ -986,16 +997,16 @@ export class Decimal128 {
986997
}
987998

988999
if (this.isNegative()) {
989-
return this.neg().divide(x).neg();
1000+
return this.negate().divide(x).negate();
9901001
}
9911002

9921003
if (x.isNegative()) {
993-
return this.divide(x.neg()).neg();
1004+
return this.divide(x.negate()).negate();
9941005
}
9951006

9961007
let adjust = 0;
997-
let dividendCoefficient = this.significand();
998-
let divisorCoefficient = x.significand();
1008+
let dividendCoefficient = this.coefficient();
1009+
let divisorCoefficient = x.coefficient();
9991010

10001011
if (dividendCoefficient !== 0n) {
10011012
while (dividendCoefficient < divisorCoefficient) {
@@ -1029,7 +1040,9 @@ export class Decimal128 {
10291040
}
10301041
}
10311042

1032-
let resultExponent = this.exponent() - (x.exponent() + adjust);
1043+
let ourExponent = this.quantum();
1044+
let theirExponent = x.quantum();
1045+
let resultExponent = ourExponent - (theirExponent + adjust);
10331046
return new Decimal128(`${resultCoefficient}E${resultExponent}`);
10341047
}
10351048

@@ -1061,7 +1074,7 @@ export class Decimal128 {
10611074
return new Decimal128(new Decimal({ cohort: roundedV, quantum: q }));
10621075
}
10631076

1064-
neg(): Decimal128 {
1077+
negate(): Decimal128 {
10651078
if (this.isNaN()) {
10661079
return this.clone();
10671080
}
@@ -1106,11 +1119,11 @@ export class Decimal128 {
11061119
}
11071120

11081121
if (this.isNegative()) {
1109-
return this.neg().remainder(d).neg();
1122+
return this.negate().remainder(d).negate();
11101123
}
11111124

11121125
if (d.isNegative()) {
1113-
return this.remainder(d.neg());
1126+
return this.remainder(d.negate());
11141127
}
11151128

11161129
if (!this.isFinite()) {

tests/Decimal128/divide.test.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -164,14 +164,14 @@ describe("examples from the General Decimal Arithmetic Specification", () => {
164164
expect(
165165
new Decimal128("8.00")
166166
.divide(new Decimal128("2"))
167-
.toString({ normalize: false })
167+
.toString({ preserveTrailingZeroes: true })
168168
).toStrictEqual("4.00");
169169
});
170170
test("example seven", () => {
171171
expect(
172172
new Decimal128("2.400")
173173
.divide(new Decimal128("2.0"))
174-
.toString({ normalize: false })
174+
.toString({ preserveTrailingZeroes: true })
175175
).toStrictEqual("1.20");
176176
});
177177
test("example eight", () => {
@@ -188,7 +188,7 @@ describe("examples from the General Decimal Arithmetic Specification", () => {
188188
expect(
189189
new Decimal128("2.40E+6")
190190
.divide(new Decimal128("2"))
191-
.toString({ format: "exponential" })
191+
.toExponential()
192192
).toStrictEqual("1.20e+6");
193193
});
194194
});

tests/Decimal128/neg.test.js

-52
This file was deleted.

tests/Decimal128/negate.test.js

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { Decimal128 } from "../../src/Decimal128.mjs";
2+
3+
const MAX_SIGNIFICANT_DIGITS = 34;
4+
const bigDigits = "9".repeat(MAX_SIGNIFICANT_DIGITS);
5+
6+
describe("negate", () => {
7+
test("minus zero", () => {
8+
expect(new Decimal128("-0").negate().toString()).toStrictEqual("0");
9+
});
10+
test("zero", () => {
11+
expect(new Decimal128("0").negate().toString()).toStrictEqual("-0");
12+
});
13+
test("NaN", () => {
14+
expect(new Decimal128("NaN").negate().toString()).toStrictEqual("NaN");
15+
});
16+
test("negative number", () => {
17+
expect(new Decimal128("-42.51").negate().toString()).toStrictEqual(
18+
"42.51"
19+
);
20+
});
21+
test("positive number", () => {
22+
expect(new Decimal128("42.51").negate().toString()).toStrictEqual(
23+
"-42.51"
24+
);
25+
});
26+
test("preserve trailing zeros", () => {
27+
expect(
28+
new Decimal128("-42.510")
29+
.negate()
30+
.toString({ preserveTrailingZeroes: true })
31+
).toStrictEqual("42.510");
32+
});
33+
test("-Infinity", () => {
34+
expect(new Decimal128("-Infinity").negate().toString()).toStrictEqual(
35+
"Infinity"
36+
);
37+
});
38+
test("Infinity", () => {
39+
expect(new Decimal128("Infinity").negate().toString()).toStrictEqual(
40+
"-Infinity"
41+
);
42+
});
43+
test("limit of digits", () => {
44+
expect(
45+
new Decimal128("-" + bigDigits).negate().toString()
46+
).toStrictEqual(bigDigits);
47+
});
48+
});

0 commit comments

Comments
 (0)