Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
jessealama committed Sep 11, 2023
1 parent f0d8f69 commit d9637b3
Show file tree
Hide file tree
Showing 10 changed files with 751 additions and 918 deletions.
789 changes: 663 additions & 126 deletions src/decimal128.mts

Large diffs are not rendered by default.

723 changes: 0 additions & 723 deletions src/rationalDecimal128.mts

This file was deleted.

4 changes: 2 additions & 2 deletions tests/abs.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { Decimal128 } from "../src/decimal128.mjs";

describe("absolute value", function () {
test("simple positive case", () => {
expect(Decimal128.abs("123.456")).toStrictEqual("123.456");
expect(new Decimal128("123.456").abs().toString()).toStrictEqual("123.456");
});
test("simple negative case", () => {
expect(Decimal128.abs("-123.456")).toStrictEqual("123.456");
expect(new Decimal128("-123.456").abs().toString()).toStrictEqual("123.456");
});
});
30 changes: 17 additions & 13 deletions tests/add.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,43 @@ import { Decimal128 } from "../src/decimal128.mjs";
const MAX_SIGNIFICANT_DIGITS = 34;
const bigDigits = "9".repeat(MAX_SIGNIFICANT_DIGITS);

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

describe("addition" + "", () => {
test("one plus one equals two", () => {
expect(Decimal128.add("1", "1")).toStrictEqual("2");
expect(one.add(one).toString()).toStrictEqual("2");
});
test("one plus minus one equals zero", () => {
expect(Decimal128.add("1", "-1")).toStrictEqual("0");
expect(Decimal128.add("-1", "1")).toStrictEqual("0");
expect(one.add(minusOne).toString()).toStrictEqual("0");
expect(minusOne.add(one).toString()).toStrictEqual("0");
});
test("two negatives", () => {
expect(Decimal128.add("-1", "-99")).toStrictEqual("-100");
expect(minusOne.add(new Decimal128("-99").toString())).toStrictEqual("-100");
});
test("0.1 + 0.2 = 0.3", () => {
let a = "0.1";
let b = "0.2";
let c = "0.3";
expect(Decimal128.add(a, b)).toStrictEqual(c);
expect(Decimal128.add(b, a)).toStrictEqual(c);
expect(new Decimal128(a).add(new Decimal128(b)).toString()).toStrictEqual(c);
expect(new Decimal128(b).add(new Decimal128(a)).toString()).toStrictEqual(c);
});
let big = new Decimal128(bigDigits);
test("big plus zero is OK", () => {
expect(Decimal128.add(bigDigits, "0")).toStrictEqual(bigDigits);
expect(big.add(zero).toString()).toStrictEqual(bigDigits);
});
test("zero plus big is OK", () => {
expect(Decimal128.add("0", bigDigits)).toStrictEqual(bigDigits);
expect(zero.add(big).toString()).toStrictEqual(bigDigits);
});
test("big plus one is OK", () => {
expect(Decimal128.add(bigDigits, "1")).toStrictEqual(
Decimal128.add("1", bigDigits)
);
expect(big.add(one).toString()).toStrictEqual(one.add(big).toString());
});
test("two plus big is not OK (too many significant digits)", () => {
expect(() => Decimal128.add("2", bigDigits)).toThrow(RangeError);
expect(() => two.add(big)).toThrow(RangeError);
});
test("big plus two is not OK (too many significant digits)", () => {
expect(() => Decimal128.add(bigDigits, "2")).toThrow(RangeError);
expect(() => big.add(two)).toThrow(RangeError);
});
});
14 changes: 7 additions & 7 deletions tests/remainder.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,24 @@ describe("remainder", () => {
let a = "4.1";
let b = "1.25";
test("simple example", () => {
expect(Decimal128.remainder(a, b)).toStrictEqual("0.35");
expect(new Decimal128(a).remainder(new Decimal128(b)).toString()).toStrictEqual("0.35");
});
test("negative, with positive argument", () => {
expect(Decimal128.remainder("-4.1", b)).toStrictEqual("-0.35");
expect(new Decimal128("-4.1").remainder(new Decimal128(b)).toString()).toStrictEqual("-0.35");
});
test("negative argument", () => {
expect(Decimal128.remainder(a, "-1.25")).toStrictEqual("0.35");
expect(new Decimal128(a).remainder(new Decimal128("-1.25")).toString()).toStrictEqual("0.35");
});
test("negative, with negative argument", () => {
expect(Decimal128.remainder("-4.1", "-1.25")).toStrictEqual("-0.35");
expect(new Decimal128("-4.1").remainder(new Decimal128("-1.25")).toString()).toStrictEqual("-0.35");
});
test("divide by zero", () => {
expect(() => Decimal128.remainder("42", "0")).toThrow(RangeError);
expect(() => new Decimal128("42").remainder(new Decimal128("0"))).toThrow(RangeError);
});
test("divide by minus zero", () => {
expect(() => Decimal128.remainder("42", "-0")).toThrow(RangeError);
expect(() => new Decimal128("42").remainder(new Decimal128("-0"))).toThrow(RangeError);
});
test("cleanly divides", () => {
expect(Decimal128.remainder("10", "5")).toStrictEqual("0");
expect(new Decimal128("10").remainder(new Decimal128("5")).toString()).toStrictEqual("0");
});
});
44 changes: 22 additions & 22 deletions tests/round.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,74 +3,74 @@ import { Decimal128 } from "../src/decimal128.mjs";
describe("rounding", () => {
describe("no arguments (round to integer)", () => {
test("positive odd", () => {
expect(Decimal128.round("1.5")).toStrictEqual("2");
expect(new Decimal128("1.5").round().toString()).toStrictEqual("2");
});
test("positive even", () => {
expect(Decimal128.round("2.5")).toStrictEqual("2");
expect(new Decimal128("2.5").round().toString()).toStrictEqual("2");
});
test("round up (positive)", () => {
expect(Decimal128.round("2.6")).toStrictEqual("3");
expect(new Decimal128("2.6").round().toString()).toStrictEqual("3");
});
test("negative odd", () => {
expect(Decimal128.round("-1.5")).toStrictEqual("-2");
expect(new Decimal128("-1.5").round().toString()).toStrictEqual("-2");
});
test("negative even", () => {
expect(Decimal128.round("-2.5")).toStrictEqual("-2");
expect(new Decimal128("-2.5").round().toString()).toStrictEqual("-2");
});
test("round down (positive)", () => {
expect(Decimal128.round("1.1")).toStrictEqual("1");
expect(new Decimal128("1.1").round().toString()).toStrictEqual("1");
});
});
describe("round to one decimal place, with one decimal place available", () => {
test("positive odd", () => {
expect(Decimal128.round("1.5", 1)).toStrictEqual("2");
expect(new Decimal128("1.5").round(1).toString()).toStrictEqual("2");
});
test("positive even", () => {
expect(Decimal128.round("2.5", 1)).toStrictEqual("2");
expect(new Decimal128("2.5").round(1).toString()).toStrictEqual("2");
});
test("round up (positive)", () => {
expect(Decimal128.round("2.6", 1)).toStrictEqual("3");
expect(new Decimal128("2.6").round(1).toString()).toStrictEqual("3");
});
test("negative odd", () => {
expect(Decimal128.round("-1.5", 1)).toStrictEqual("-2");
expect(new Decimal128("-1.5").round(1).toString()).toStrictEqual("-2");
});
test("negative even", () => {
expect(Decimal128.round("-2.5", 1)).toStrictEqual("-2");
expect(new Decimal128("-2.5").round(1).toString()).toStrictEqual("-2");
});
test("round down (positive)", () => {
expect(Decimal128.round("1.1", 1).toString()).toStrictEqual("1");
expect(new Decimal128("1.1").round(1).toString()).toStrictEqual("1");
});
});
describe("round to one decimal place, more than one decimal place available", () => {
test("positive odd", () => {
expect(Decimal128.round("1.75", 1)).toStrictEqual("1.8");
expect(new Decimal128("1.75").round(1).toString()).toStrictEqual("1.8");
});
test("positive even", () => {
expect(Decimal128.round("2.55", 1)).toStrictEqual("2.6");
expect(new Decimal128("2.55").round( 1).toString()).toStrictEqual("2.6");
});
test("round up (positive)", () => {
expect(Decimal128.round("2.26", 1)).toStrictEqual("2.3");
expect(new Decimal128("2.26").round( 1).toString()).toStrictEqual("2.3");
});
test("negative odd", () => {
expect(Decimal128.round("-1.95", 1)).toStrictEqual("-2");
expect(new Decimal128("-1.95").round(1).toString()).toStrictEqual("-2");
});
test("negative even", () => {
expect(Decimal128.round("-2.65", 1)).toStrictEqual("-2.6");
expect(new Decimal128("-2.65").round(1).toString()).toStrictEqual("-2.6");
});
test("round down (positive)", () => {
expect(Decimal128.round("1.81", 1)).toStrictEqual("1.8");
expect(new Decimal128("1.81").round(1).toString()).toStrictEqual("1.8");
});
});
test("round integer", () => {
expect(Decimal128.round("42", 6)).toStrictEqual("42");
expect(new Decimal128("42").round(6).toString()).toStrictEqual("42");
});
test("round with non-number number of digits", () => {
expect(() => Decimal128.round("42", "1")).toThrow(TypeError);
expect(() => new Decimal128("42").round( "1")).toThrow(TypeError);
});
test("round with non-integer number of digits", () => {
expect(() => Decimal128.round("42", 1.5)).toThrow(TypeError);
expect(() => new Decimal128("42").round(1.5)).toThrow(TypeError);
});
test("round with negative number of digits", () => {
expect(() => Decimal128.round("42", -1)).toThrow(RangeError);
expect(() => new Decimal128("42").round(-1)).toThrow(RangeError);
});
});
24 changes: 13 additions & 11 deletions tests/string.test.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,39 @@
import { Decimal128 } from "../src/decimal128.mjs";
import { expectDecimal128 } from "./util.js";

const d = "123.456";

describe("to decimal places", function () {
const decimalD = new Decimal128(d);
test("more digits than available means no change", () => {
expect(Decimal128.toDecimalPlaces(d, 7)).toStrictEqual("123.456");
expectDecimal128(decimalD.toDecimalPlaces(7), d);
});
test("same number of digits as available means no change", () => {
expect(Decimal128.toDecimalPlaces(d, 6)).toStrictEqual("123.456");
expectDecimal128(decimalD.toDecimalPlaces(6), d);
});
test("round if number has more digits than requested (1)", () => {
expect(Decimal128.toDecimalPlaces(d, 5)).toStrictEqual("123.456");
expectDecimal128(decimalD.toDecimalPlaces(5), d);
});
test("round if number has more digits than requested (2)", () => {
expect(Decimal128.toDecimalPlaces(d, 4)).toStrictEqual("123.456");
expectDecimal128(decimalD.toDecimalPlaces(4), d);
});
test("round if number has more digits than requested (3)", () => {
expect(Decimal128.toDecimalPlaces(d, 3)).toStrictEqual("123.456");
expectDecimal128(decimalD.toDecimalPlaces(3), d);
});
test("round if number has more digits than requested (4)", () => {
expect(Decimal128.toDecimalPlaces(d, 2)).toStrictEqual("123.46");
expectDecimal128(decimalD.toDecimalPlaces(2), "123.46");
});
test("round if number has more digits than requested (5)", () => {
expect(Decimal128.toDecimalPlaces(d, 1)).toStrictEqual("123.5");
expectDecimal128(decimalD.toDecimalPlaces(1), "123.5");
});
test("zero decimal places", () => {
expect(Decimal128.toDecimalPlaces(d, 0)).toStrictEqual("123");
expectDecimal128(decimalD.toDecimalPlaces(0), "123");
});
test("negative number of decimal places", () => {
expect(() => Decimal128.toDecimalPlaces(d, -1)).toThrow(RangeError);
expect(() => decimalD.toDecimalPlaces(-1)).toThrow(RangeError);
});
test("non-integer number of decimal places", () => {
expect(() => Decimal128.toDecimalPlaces(d, 1.5)).toThrow(TypeError);
expect(() => decimalD.toDecimalPlaces(1.5).toThrow(TypeError));
});
});

Expand All @@ -44,6 +46,6 @@ describe("to exponential string", () => {
1: "1E0",
};
for (let [input, output] of Object.entries(data)) {
expect(Decimal128.toExponentialString(input)).toStrictEqual(output);
expectDecimal128(new Decimal128(input).toExponentialString(), output);
}
});
12 changes: 7 additions & 5 deletions tests/subtract.test.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
import { Decimal128 } from "../src/decimal128.mjs";
import { expectDecimal128 } from "./util.js";

const MAX_SIGNIFICANT_DIGITS = 34;
let bigDigits = "9".repeat(MAX_SIGNIFICANT_DIGITS);

describe("subtraction", () => {
test("subtract decimal part", () => {
expect(Decimal128.subtract("123.456", "0.456")).toStrictEqual("123");
expectDecimal128(new Decimal128("123.456").subtract(new Decimal128("0.456")), "123");
});
test("minus negative number", () => {
expect(Decimal128.subtract("0.1", "-0.2")).toStrictEqual("0.3");
expectDecimal128(new Decimal128("0.1").subtract(new Decimal128("-0.2")), "0.3");
});
test("subtract two negatives", () => {
expect(Decimal128.subtract("-1.9", "-2.7")).toStrictEqual("0.8");
expectDecimal128(new Decimal128("-1.9").subtract(new Decimal128("-2.7")), "0.8");
});
const big = new Decimal128(bigDigits);
test("close to range limit", () => {
expect(Decimal128.subtract(bigDigits, "9")).toStrictEqual(
expectDecimal128(big.subtract(new Decimal128("9")),
"9".repeat(MAX_SIGNIFICANT_DIGITS - 1) + "0"
);
});
test("integer overflow", () => {
expect(() => Decimal128.subtract("-" + bigDigits, "9")).toThrow(
expect(() => new Decimal128("-" + bigDigits).subtract(new Decimal128("9"))).toThrow(
RangeError
);
});
Expand Down
21 changes: 12 additions & 9 deletions tests/truncate.test.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { Decimal128 } from "../src/decimal128.mjs";
import { expectDecimal128 } from "./util.js";


describe("truncate", () => {
test("basic example", () => {
expect(Decimal128.truncate("123.45678")).toStrictEqual("123");
});
test("truncate negative", () => {
expect(Decimal128.truncate("-42.99")).toStrictEqual("-42");
});
test("between zero and one", () => {
expect(Decimal128.truncate("0.00765")).toStrictEqual("0");
});
let data = {
"123.45678": "123",
"-42.99": "-42",
"0.00765": "0"
};
for (let [key, value] of Object.entries(data)) {
test(key, () => {
expectDecimal128(new Decimal128(key).truncate(), value)
});
}
});
8 changes: 8 additions & 0 deletions tests/util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Decimal128 } from "../src/decimal128.mjs";

export function expectDecimal128(a, b)
{
let lhs = a instanceof Decimal128 ? a.toString() : a;
let rhs = b instanceof Decimal128 ? b.toString() : b;
expect(lhs).toStrictEqual(rhs);
}

0 comments on commit d9637b3

Please sign in to comment.