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

Commit 12d3da2

Browse files
authored
Add examples and normalize strategy (#70)
* Add examples in new `examples` directory * Make sure that our examples don't crash * Use object methods rather than static methods * Normalize by default Also, make the API match what the spec says: remove `toExponentialString` and `toDecimalPlaces`, bringing their functionality into `toString`, which now takes options. * Show Node and NPM versions in CI pipeline * Add more info about environment in the CI pipeline * Upgrade outdated NPM dependencies * Remove unused code
1 parent 03eb513 commit 12d3da2

26 files changed

+776
-1166
lines changed

.github/workflows/push.yaml

+17-2
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,28 @@ jobs:
55
runs-on: ubuntu-latest
66
steps:
77
- uses: actions/checkout@master
8+
- uses: actions/setup-node@master
9+
with:
10+
node-version: 20
11+
- name: check node version
12+
run: node --version
13+
- name: check npm version
14+
run: npm --version
15+
- name: check npx path
16+
run: which npx
17+
- name: check npx version
18+
run: npx --version
819
- name: npm install
920
run: npm install
1021
- name: lint
1122
run: npm run lint
1223
- name: compile typescript
1324
run: tsc
1425
- name: test
15-
run: npx c8 npx jest
16-
- name: coverage
26+
run: npm run test
27+
- name: generate coverage
28+
run: npm run coverage
29+
- name: check coverage
1730
run: npx c8 check-coverage --lines 99 --functions 99 --branches 99 --statements 99
31+
- name: examples do not crash
32+
run: for f in examples/*.js; do node $f || exit 1; done

examples/bill.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Decimal128 } from "../src/decimal128.mjs";
2+
3+
const zero = new Decimal128("0");
4+
const one = new Decimal128("1");
5+
6+
function calculateBill(items, tax) {
7+
let taxRate = new Decimal128(tax).add(one);
8+
let total = items.reduce((total, { price, count }) => {
9+
return total.add(new Decimal128(price).multiply(new Decimal128(count)));
10+
}, zero);
11+
return total.multiply(taxRate);
12+
}
13+
14+
const items = [
15+
{ price: "1.25", count: "5" },
16+
{ price: "5.00", count: "1" },
17+
];
18+
const tax = "0.0735";
19+
console.log(calculateBill(items, tax).toString());

examples/floor.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function floor(d) {
2+
return d.round(0, "floor");
3+
}

examples/mortgage.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Decimal128 } from "../src/decimal128.mjs";
2+
import { pow } from "./pow.js";
3+
4+
const one = new Decimal128("1");
5+
const paymentsPerYear = new Decimal128("12");
6+
7+
function calculateMonthlyPayment(p, r, y) {
8+
let principal = new Decimal128(p);
9+
let annualInterestRate = new Decimal128(r);
10+
let years = new Decimal128(y);
11+
const monthlyInterestRate = annualInterestRate.divide(paymentsPerYear);
12+
const paymentCount = paymentsPerYear.multiply(years);
13+
const onePlusInterestRate = monthlyInterestRate.add(one);
14+
const ratePower = pow(onePlusInterestRate, paymentCount);
15+
16+
let x = principal.multiply(monthlyInterestRate);
17+
let numerator = x.multiply(ratePower);
18+
19+
let denominator = ratePower.subtract(one);
20+
21+
return numerator.divide(denominator);
22+
}
23+
24+
console.log(calculateMonthlyPayment("5000000", "0.05", "30").toString());

examples/pow.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Decimal128 } from "../src/decimal128.mjs";
2+
3+
const one = new Decimal128("1");
4+
5+
function pow(a, b) {
6+
let i = one;
7+
let result = a;
8+
while (-1 === i.cmp(b)) {
9+
result = result.multiply(a);
10+
i = i.add(one);
11+
}
12+
return result;
13+
}
14+
15+
export { pow };

examples/round.js

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Example with different rounding modes
2+
3+
// Examples from the Intl.NumberFormat spec
4+
5+
import { Decimal128 } from "../src/decimal128.mjs";
6+
7+
let minusOnePointFive = new Decimal128("-1.5");
8+
let zeroPointFour = new Decimal128("0.4");
9+
let zeroPointFive = new Decimal128("0.5");
10+
let zeroPointSix = new Decimal128("0.6");
11+
let onePointFive = new Decimal128("1.5");
12+
13+
// ceiling
14+
"-1" === minusOnePointFive.round(0, "ceil").toString();
15+
"1" === zeroPointFour.round(0, "ceil").toString();
16+
"1" === zeroPointFive.round(0, "ceil").toString();
17+
"1" === zeroPointSix.round(0, "ceil").toString();
18+
"2" === onePointFive.round(0, "ceil").toString();
19+
20+
// floor
21+
"-2" === minusOnePointFive.round(0, "floor").toString();
22+
"0" === zeroPointFour.round(0, "floor").toString();
23+
"0" === zeroPointFive.round(0, "floor").toString();
24+
"0" === zeroPointSix.round(0, "floor").toString();
25+
"1" === onePointFive.round(0, "floor").toString();
26+
27+
// expand
28+
"-2" === minusOnePointFive.round(0, "expand").toString();
29+
"1" === zeroPointFour.round(0, "expand").toString();
30+
"1" === zeroPointFive.round(0, "expand").toString();
31+
"1" === zeroPointSix.round(0, "expand").toString();
32+
"2" === onePointFive.round(0, "expand").toString();
33+
34+
// truncate
35+
"-1" === minusOnePointFive.round(0, "trunc").toString();
36+
"0" === zeroPointFour.round(0, "trunc").toString();
37+
"0" === zeroPointFive.round(0, "trunc").toString();
38+
"0" === zeroPointSix.round(0, "trunc").toString();
39+
"1" === onePointFive.round(0, "trunc").toString();
40+
41+
// round ties to ceiling
42+
"-1" === minusOnePointFive.round(0, "halfCeil").toString();
43+
"0" === zeroPointFour.round(0, "halfCeil").toString();
44+
"1" === zeroPointFive.round(0, "halfCeil").toString();
45+
"1" === zeroPointSix.round(0, "halfCeil").toString();
46+
"2" === onePointFive.round(0, "halfCeil").toString();
47+
48+
// round ties to floor
49+
"-2" === minusOnePointFive.round(0, "halfFloor").toString();
50+
"0" === zeroPointFour.round(0, "halfFloor").toString();
51+
"0" === zeroPointFive.round(0, "halfFloor").toString();
52+
"1" === zeroPointSix.round(0, "halfFloor").toString();
53+
"1" === onePointFive.round(0, "halfFloor").toString();
54+
55+
// round ties away from zero
56+
"-2" === minusOnePointFive.round(0, "halfExpand").toString();
57+
"0" === zeroPointFour.round(0, "halfExpand").toString();
58+
"1" === zeroPointFive.round(0, "halfExpand").toString();
59+
"1" === zeroPointSix.round(0, "halfExpand").toString();
60+
"2" === onePointFive.round(0, "halfExpand").toString();
61+
62+
// round ties to toward zero
63+
"-1" === minusOnePointFive.round(0, "halfTrunc").toString();
64+
"0" === zeroPointFour.round(0, "halfTrunc").toString();
65+
"0" === zeroPointFive.round(0, "halfTrunc").toString();
66+
"1" === zeroPointSix.round(0, "halfTrunc").toString();
67+
"1" === onePointFive.round(0, "halfTrunc").toString();
68+
69+
// round ties to even
70+
"-2" === minusOnePointFive.round(0, "halfEven").toString();
71+
"0" === zeroPointFour.round(0, "halfEven").toString();
72+
"0" === zeroPointFive.round(0, "halfEven").toString();
73+
"1" === zeroPointSix.round(0, "halfEven").toString();
74+
"2" === onePointFive.round(0, "halfEven").toString();

examples/step.js

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Example for stepping a value up/down
2+
import { pow } from "./pow.js";
3+
import { Decimal128 } from "../src/decimal128.mjs";
4+
5+
const ten = new Decimal128("10");
6+
7+
function stepUp(d, n, x) {
8+
let increment = pow(ten, x);
9+
return d.add(n.multiply(increment));
10+
}
11+
12+
let starting = new Decimal128("1.23");
13+
let stepped = stepUp(starting, new Decimal128("3"), new Decimal128("-4"));
14+
console.log(stepped.toString({ numDecimalDigits: 4 })); // 1.2305

0 commit comments

Comments
 (0)