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

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
jessealama committed Jun 25, 2024
1 parent 4f5ee87 commit 569e881
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 536 deletions.
20 changes: 10 additions & 10 deletions src/Decimal128.mts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* @author Jesse Alama <[email protected]>
*/

import { Digit, DigitOrTen, RoundingMode, ROUNDING_MODES } from "./common.mjs";
import { RoundingMode, ROUNDING_MODES } from "./common.mjs";
import { Rational } from "./Rational.mjs";
import { Decimal } from "./Decimal.mjs";

Expand Down Expand Up @@ -596,7 +596,7 @@ export class Decimal128 {
*
* @param x
*/
private cmp(x: Decimal128): number {
cmp(x: Decimal128): number {
if (this.isNaN() || x.isNaN()) {
return NaN;
}
Expand All @@ -621,20 +621,20 @@ export class Decimal128 {
return x.isNegative() ? 1 : -1;
}

if (this.isZero()) {
if (x.isZero()) {
return 0;
}

return x.isNegative() ? 1 : -1;
}

let ourCohort = this.cohort() as Rational;
let theirCohort = x.cohort() as Rational;

return ourCohort.cmp(theirCohort);
}

lessThan(x: Decimal128): boolean {
return this.cmp(x) === -1;
}

equals(x: Decimal128): boolean {
return this.cmp(x) === 0;
}

abs(): Decimal128 {
if (this.isNaN()) {
return new Decimal128(NAN);
Expand Down
6 changes: 0 additions & 6 deletions tests/Decimal128/abs.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,6 @@ import { Decimal128 } from "../../src/Decimal128.mjs";
const MAX_SIGNIFICANT_DIGITS = 34;
const bigDigits = "9".repeat(MAX_SIGNIFICANT_DIGITS);

const zero = new Decimal128("0");
const minusZero = new Decimal128("-0");
const one = new Decimal128("1");
const minusOne = new Decimal128("-1");
const two = new Decimal128("2");

describe("abs", () => {
test("minus zero", () => {
expect(new Decimal128("-0").abs().toString()).toStrictEqual("0");
Expand Down
198 changes: 198 additions & 0 deletions tests/Decimal128/cmp.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
import { Decimal128 } from "../../src/Decimal128.mjs";

const MAX_SIGNIFICANT_DIGITS = 34;
const nan = new Decimal128("NaN");
const zero = new Decimal128("0");
const negZero = new Decimal128("-0");
const one = new Decimal128("1");

describe("equals", () => {
let d1 = new Decimal128("987.123");
let d2 = new Decimal128("123.456789");
test("simple example", () => {
expect(d1.cmp(d1)).toStrictEqual(0);
});
test("non-example", () => {
expect(d1.cmp(d2)).toStrictEqual(1);
});
test("negative numbers", () => {
let a = new Decimal128("-123.456");
expect(a.cmp(a)).toStrictEqual(0);
});
test("integer part is the same, decimal part is not", () => {
let a = new Decimal128("42.678");
let b = new Decimal128("42.6789");
expect(a.cmp(b)).toStrictEqual(-1);
});
test("negative and positive are different", () => {
expect(
new Decimal128("-123.456").cmp(new Decimal128("123.456"))
).toStrictEqual(-1);
});
test("limit of significant digits", () => {
expect(
new Decimal128("0.4166666666666666666666666666666667").cmp(
new Decimal128("0.41666666666666666666666666666666666")
)
).toStrictEqual(0);
});
test("beyond limit of significant digits", () => {
expect(
new Decimal128("0.41666666666666666666666666666666667").cmp(
new Decimal128("0.41666666666666666666666666666666666")
)
).toStrictEqual(0);
});
test("non-example", () => {
expect(
new Decimal128("0.037").cmp(new Decimal128("0.037037037037"))
).toStrictEqual(-1);
});
describe("examples from a presentation", () => {
let a = new Decimal128("1.00");
let b = new Decimal128("1.0000");
let c = new Decimal128("1.0001");
let d = new Decimal128("0.9999");
test("use mathematical equality by default", () => {
expect(a.cmp(b)).toStrictEqual(0);
});
test("mathematically distinct", () => {
expect(a.cmp(c)).toStrictEqual(-1);
});
test("mathematically distinct, again", () => {
expect(b.cmp(d)).toStrictEqual(1);
});
test("mathematically distinct, once more", () => {
expect(a.cmp(d)).toStrictEqual(1);
});
});
});

describe("many digits", () => {
test("non-integers get rounded", () => {
expect(
new Decimal128("0." + "4".repeat(MAX_SIGNIFICANT_DIGITS + 50)).cmp(
new Decimal128("0." + "4".repeat(MAX_SIGNIFICANT_DIGITS))
)
).toStrictEqual(0);
});
test("non-equality within limits", () => {
expect(
new Decimal128("0." + "4".repeat(33)).cmp(
new Decimal128("0." + "4".repeat(MAX_SIGNIFICANT_DIGITS))
)
).toStrictEqual(-1);
});
describe("NaN", () => {
test("NaN equals NaN throws", () => {
expect(nan.cmp(nan)).toStrictEqual(NaN);
});
test("number equals NaN throws", () => {
expect(one.cmp(nan)).toStrictEqual(NaN);
});
test("NaN equals number throws", () => {
expect(nan.cmp(one)).toStrictEqual(NaN);
});
});
describe("minus zero", () => {
test("left hand", () => {
expect(negZero.cmp(zero)).toStrictEqual(0);
});
test("right hand", () => {
expect(zero.cmp(negZero)).toStrictEqual(0);
});
test("both arguments", () => {
expect(negZero.cmp(negZero)).toStrictEqual(0);
});
});
describe("infinity", () => {
let posInf = new Decimal128("Infinity");
let negInf = new Decimal128("-Infinity");
test("positive infinity vs number", () => {
expect(posInf.cmp(one)).toStrictEqual(1);
});
test("negative infinity vs number", () => {
expect(negInf.cmp(one)).toStrictEqual(-1);
});
test("negative infintity vs positive infinity", () => {
expect(negInf.cmp(posInf)).toStrictEqual(-1);
});
test("positive infinity vs negative infinity", () => {
expect(posInf.cmp(negInf)).toStrictEqual(1);
});
test("positive infinity both arguments", () => {
expect(posInf.cmp(posInf)).toStrictEqual(0);
});
test("negative infinity both arguments", () => {
expect(negInf.cmp(negInf)).toStrictEqual(0);
});
test("compare number to positive infinity", () => {
expect(one.cmp(posInf)).toStrictEqual(-1);
});
test("compare number to negative infinity", () => {
expect(one.cmp(negInf)).toStrictEqual(1);
});
});
});

describe("zero", () => {
test("positive zero", () => {
expect(zero.cmp(zero)).toStrictEqual(0);
});
test("negative zero", () => {
expect(negZero.cmp(negZero)).toStrictEqual(0);
});
test("negative zero vs zero", () => {
expect(negZero.cmp(zero)).toStrictEqual(0);
});
});

describe("normalization", () => {
let d1 = new Decimal128("1.2");
let d2 = new Decimal128("1.20");
let d3 = new Decimal128("1.200");
test("compare normalized to normalized", () => {
expect(d1.cmp(d2)).toStrictEqual(0);
});
test("compare normalized to normalized", () => {
expect(d2.cmp(d3)).toStrictEqual(0);
});
test("compare normalized to normalized", () => {
expect(d1.cmp(d3)).toStrictEqual(0);
});
});

describe("examples from the General Decimal Arithmetic specification", () => {
describe("compare", () => {
test("example one", () => {
expect(
new Decimal128("2.1").cmp(new Decimal128("3"))
).toStrictEqual(-1);
});
test("example two", () => {
expect(
new Decimal128("2.1").cmp(new Decimal128("2.1"))
).toStrictEqual(0);
});
test("example three", () => {
expect(
new Decimal128("2.1").cmp(new Decimal128("2.10"))
).toStrictEqual(0);
});
test("example four", () => {
expect(
new Decimal128("3").cmp(new Decimal128("2.1"))
).toStrictEqual(1);
});
test("example five", () => {
expect(
new Decimal128("2.1").cmp(new Decimal128("-3"))
).toStrictEqual(1);
});
test("example six", () => {
expect(
new Decimal128("-3").cmp(new Decimal128("2.1"))
).toStrictEqual(-1);
});
});
});
Loading

0 comments on commit 569e881

Please sign in to comment.