@numio/bigmath 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -3
- package/index.d.ts +2 -1
- package/index.js +2 -1
- package/package.json +1 -1
- package/src/add/index.d.ts +1 -1
- package/src/add/index.js +1 -1
- package/src/div/index.d.ts +1 -1
- package/src/div/index.js +1 -1
- package/src/mul/index.d.ts +1 -1
- package/src/mul/index.js +1 -1
- package/src/round/constants.d.ts +7 -0
- package/src/round/constants.js +14 -0
- package/src/round/index.d.ts +3 -0
- package/src/round/index.js +45 -0
- package/src/round/types.d.ts +10 -0
- package/src/round/utils.d.ts +4 -0
- package/src/round/utils.js +60 -0
- package/src/sub/index.d.ts +1 -1
- package/src/sub/index.js +1 -1
package/README.md
CHANGED
@@ -29,9 +29,15 @@ This library is particularly useful in scenarios where precise calculations with
|
|
29
29
|
|
30
30
|
### Latest update
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
Added rounding
|
33
|
+
* round up
|
34
|
+
* round down
|
35
|
+
* half-up
|
36
|
+
* half-down
|
37
|
+
* half-even
|
38
|
+
* half-odd
|
39
|
+
* decimal places to be rounded
|
40
|
+
* significant figures decimals to be rounded
|
35
41
|
|
36
42
|
# Install:
|
37
43
|
|
@@ -107,6 +113,59 @@ const negative = div(["-2", "-3", "2"]); // 3
|
|
107
113
|
div("10", "3"); // 3.33333
|
108
114
|
```
|
109
115
|
|
116
|
+
### Round
|
117
|
+
```javascript
|
118
|
+
round("-1.12345"); // -1
|
119
|
+
round("1.5"); // 2
|
120
|
+
round("1.0"); // 1
|
121
|
+
round("0.00001"); // 0
|
122
|
+
round("9.9"); // 10
|
123
|
+
```
|
124
|
+
|
125
|
+
### Round at position
|
126
|
+
```javascript
|
127
|
+
round("1.12345", { decimals: 1 }); // 1.1
|
128
|
+
round("1.12345", { decimals: 2 }); // 1.12
|
129
|
+
round("1.12234", { decimals: 0 }); // 1
|
130
|
+
round("9.999", { decimals: 2 }); // 10
|
131
|
+
```
|
132
|
+
|
133
|
+
### Round modes
|
134
|
+
```javascript
|
135
|
+
round("1.11", { decimals: 1, roundMode: "up" }); // 1.2
|
136
|
+
round("1.19", { decimals: 1, roundMode: "up" }); // 1.2
|
137
|
+
|
138
|
+
round("1.11", { decimals: 1, roundMode: "down" }); // 1.1
|
139
|
+
round("1.19", { decimals: 1, roundMode: "down" }); // 1.1
|
140
|
+
|
141
|
+
round("1.15", { decimals: 1, roundMode: "half-up" }); // 1.2
|
142
|
+
round("1.15", { decimals: 1, roundMode: "half-down" }); // 1.1
|
143
|
+
|
144
|
+
round("1.15", { decimals: 1, roundMode: "half-even" }); // 1.2
|
145
|
+
round("1.25", { decimals: 1, roundMode: "half-even" }); // 1.2
|
146
|
+
round("1.35", { decimals: 1, roundMode: "half-even" }); // 1.4
|
147
|
+
round("1.45", { decimals: 1, roundMode: "half-even" }); // 1.4
|
148
|
+
round("1.55", { decimals: 1, roundMode: "half-even" }); // 1.6
|
149
|
+
|
150
|
+
round("1.15", { decimals: 1, roundMode: "half-odd" }); // 1.1
|
151
|
+
round("1.25", { decimals: 1, roundMode: "half-odd" }); // 1.3
|
152
|
+
round("1.35", { decimals: 1, roundMode: "half-odd" }); // 1.3
|
153
|
+
round("1.45", { decimals: 1, roundMode: "half-odd" }); // 1.5
|
154
|
+
round("1.55", { decimals: 1, roundMode: "half-odd" }); // 1.5
|
155
|
+
```
|
156
|
+
|
157
|
+
### Round with "significant figures" flag
|
158
|
+
```javascript
|
159
|
+
round("0.000119", { decimals: 2, sigFig: false }); // 0
|
160
|
+
round("0.000119", { decimals: 2, sigFig: true }); // 0.00012
|
161
|
+
|
162
|
+
round("0.0019", { decimals: 1, sigFig: true, roundMode: "down" }); // 0.001
|
163
|
+
round("0.0011", { decimals: 1, sigFig: true, roundMode: "up" }); // 0.002
|
164
|
+
|
165
|
+
round("1.000119", { decimals: 2, sigFig: false }); // 1
|
166
|
+
round("1.000119", { decimals: 2, sigFig: true }); // 1
|
167
|
+
```
|
168
|
+
|
110
169
|
Does not have a limitation on the number of digits. You can use any length you'd
|
111
170
|
like
|
112
171
|
|
package/index.d.ts
CHANGED
@@ -2,4 +2,5 @@ import { add } from "./src/add/index.d.ts";
|
|
2
2
|
import { mul } from "./src/mul/index.d.ts";
|
3
3
|
import { sub } from "./src/sub/index.d.ts";
|
4
4
|
import { div } from "./src/div/index.d.ts";
|
5
|
-
|
5
|
+
import { round } from "./src/round/index.d.ts";
|
6
|
+
export { add, div, mul, round, sub };
|
package/index.js
CHANGED
@@ -2,4 +2,5 @@ import { add } from "./src/add/index.js";
|
|
2
2
|
import { mul } from "./src/mul/index.js";
|
3
3
|
import { sub } from "./src/sub/index.js";
|
4
4
|
import { div } from "./src/div/index.js";
|
5
|
-
|
5
|
+
import { round } from "./src/round/index.js";
|
6
|
+
export { add, div, mul, round, sub };
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@numio/bigmath",
|
3
3
|
"description": "@numio/bigmath is an arbitrary-precision arithmetic library. It can be used for basic operations with decimal numbers (integers and float)",
|
4
|
-
"version": "1.0.
|
4
|
+
"version": "1.0.3",
|
5
5
|
"keywords": [
|
6
6
|
"precision",
|
7
7
|
"arithmetic",
|
package/src/add/index.d.ts
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
/** This function adds
|
1
|
+
/** This function adds numbers (as string). */
|
2
2
|
export declare function add(strs: string[]): string;
|
package/src/add/index.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import { a2sSA, s2aSA } from "../shared/utils.js";
|
2
2
|
import { subtract } from "../sub/utils.js";
|
3
3
|
import { addition } from "./utils.js";
|
4
|
-
/** This function adds
|
4
|
+
/** This function adds numbers (as string). */
|
5
5
|
export function add(strs) {
|
6
6
|
var arrays = strs.map(function (str) { return s2aSA(str); });
|
7
7
|
var inputData = arrays.reduce(function (left, right) {
|
package/src/div/index.d.ts
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
/** This function should divide
|
1
|
+
/** This function should divide numbers (as string). */
|
2
2
|
export declare const div: (strs: string[], limit?: number) => string;
|
package/src/div/index.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import { a2sMD, s2aMD } from "../shared/utils.js";
|
2
2
|
import { division } from "./utils.js";
|
3
|
-
/** This function should divide
|
3
|
+
/** This function should divide numbers (as string). */
|
4
4
|
export var div = function (strs, limit) {
|
5
5
|
if (limit === void 0) { limit = 20; }
|
6
6
|
if (strs[0] === "0")
|
package/src/mul/index.d.ts
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
/** This function multiplies
|
1
|
+
/** This function multiplies numbers (as string). */
|
2
2
|
export declare const mul: (strs: string[]) => string;
|
package/src/mul/index.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import { a2sMD, s2aMD } from "../shared/utils.js";
|
2
2
|
import { multiplication } from "./utils.js";
|
3
|
-
/** This function multiplies
|
3
|
+
/** This function multiplies numbers (as string). */
|
4
4
|
export var mul = function (strs) {
|
5
5
|
var arrays = strs.map(function (str) { return s2aMD(str); });
|
6
6
|
var inputData = arrays.reduce(function (left, right) {
|
@@ -0,0 +1,7 @@
|
|
1
|
+
export declare const UP = "up";
|
2
|
+
export declare const DOWN = "down";
|
3
|
+
export declare const HALF_UP = "half-up";
|
4
|
+
export declare const HALF_DOWN = "half-down";
|
5
|
+
export declare const HALF_EVEN = "half-even";
|
6
|
+
export declare const HALF_ODD = "half-odd";
|
7
|
+
export declare const ROUND_MODE: readonly ["up", "down", "half-up", "half-down", "half-even", "half-odd"];
|
@@ -0,0 +1,14 @@
|
|
1
|
+
export var UP = "up";
|
2
|
+
export var DOWN = "down";
|
3
|
+
export var HALF_UP = "half-up";
|
4
|
+
export var HALF_DOWN = "half-down";
|
5
|
+
export var HALF_EVEN = "half-even";
|
6
|
+
export var HALF_ODD = "half-odd";
|
7
|
+
export var ROUND_MODE = [
|
8
|
+
UP,
|
9
|
+
DOWN,
|
10
|
+
HALF_UP,
|
11
|
+
HALF_DOWN,
|
12
|
+
HALF_EVEN,
|
13
|
+
HALF_ODD,
|
14
|
+
];
|
@@ -0,0 +1,45 @@
|
|
1
|
+
import { HALF_UP } from "./constants.js";
|
2
|
+
import { calcLast, handleCarryOver, handleTail } from "./utils.js";
|
3
|
+
/** This function round number. */
|
4
|
+
export var round = function (value, options) {
|
5
|
+
var _a;
|
6
|
+
var _b, _c, _d, _e;
|
7
|
+
var roundMode = (_b = options === null || options === void 0 ? void 0 : options.roundMode) !== null && _b !== void 0 ? _b : HALF_UP;
|
8
|
+
var array = [];
|
9
|
+
var sigFig = (_c = options === null || options === void 0 ? void 0 : options.sigFig) !== null && _c !== void 0 ? _c : false;
|
10
|
+
var decimals = (_d = options === null || options === void 0 ? void 0 : options.decimals) !== null && _d !== void 0 ? _d : 0;
|
11
|
+
var isFloat = false;
|
12
|
+
var isNill = true;
|
13
|
+
for (var i = 0; i < value.length; i++) {
|
14
|
+
var charCode = value.charCodeAt(i);
|
15
|
+
if (sigFig && charCode > 48)
|
16
|
+
sigFig = false;
|
17
|
+
if (isNill && charCode > 48)
|
18
|
+
isNill = false;
|
19
|
+
if (isFloat && !sigFig)
|
20
|
+
decimals -= 1;
|
21
|
+
if (charCode === 46)
|
22
|
+
isFloat = true;
|
23
|
+
if (isFloat && decimals === 0) {
|
24
|
+
var next = (_e = value.charCodeAt(i + 1)) !== null && _e !== void 0 ? _e : 0;
|
25
|
+
var prev = value.charCodeAt(i - 1);
|
26
|
+
var curr = charCode === 46 ? prev : charCode;
|
27
|
+
var _f = calcLast(curr, next, roundMode), last = _f[0], hasCarryOver = _f[1];
|
28
|
+
if (charCode === 46)
|
29
|
+
isFloat = false;
|
30
|
+
if (hasCarryOver) {
|
31
|
+
_a = handleCarryOver(array, isFloat), array = _a[0], isFloat = _a[1];
|
32
|
+
break;
|
33
|
+
}
|
34
|
+
charCode === 46
|
35
|
+
? array[array.length - 1] += last - prev
|
36
|
+
: array.push(last);
|
37
|
+
break;
|
38
|
+
}
|
39
|
+
array.push(charCode);
|
40
|
+
}
|
41
|
+
handleTail(array, isFloat);
|
42
|
+
return (isNill && array[array.length - 1] <= 48)
|
43
|
+
? "0"
|
44
|
+
: String.fromCharCode.apply(String, array);
|
45
|
+
};
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import type { ROUND_MODE } from "./constants.d.ts";
|
2
|
+
export type Round = (value: string, options?: {
|
3
|
+
decimals?: number;
|
4
|
+
roundMode?: RoundMode;
|
5
|
+
sigFig?: boolean;
|
6
|
+
}) => string;
|
7
|
+
export type RoundMode = typeof ROUND_MODE[number];
|
8
|
+
export type HandleTail = (array: number[], isFloat: boolean) => void;
|
9
|
+
export type HandleCarryOver = (array: number[], isFloat: boolean) => [number[], boolean];
|
10
|
+
export type CalcLast = (current: number, next: number, roundMode: RoundMode) => [number, boolean];
|
@@ -0,0 +1,60 @@
|
|
1
|
+
import { DOWN, HALF_DOWN, HALF_EVEN, HALF_ODD, HALF_UP, UP, } from "./constants.js";
|
2
|
+
export var handleTail = function (array, isFloat) {
|
3
|
+
var lastIdx = array.length - 1;
|
4
|
+
while (isFloat && array[lastIdx] <= 48) {
|
5
|
+
if (array[lastIdx] === 46 || array.length === 1)
|
6
|
+
isFloat = false;
|
7
|
+
array.length > 1 && array.pop();
|
8
|
+
lastIdx -= 1;
|
9
|
+
}
|
10
|
+
};
|
11
|
+
export var handleCarryOver = function (array, isFloat) {
|
12
|
+
var _a;
|
13
|
+
var hasCarryOver = true;
|
14
|
+
var idx = array.length - 1;
|
15
|
+
var mapFloat = new Map([
|
16
|
+
[57, function () {
|
17
|
+
array.pop();
|
18
|
+
idx -= 1;
|
19
|
+
}],
|
20
|
+
[46, function () {
|
21
|
+
array.pop();
|
22
|
+
idx -= 1;
|
23
|
+
isFloat = false;
|
24
|
+
}],
|
25
|
+
[0, function () {
|
26
|
+
array[idx] += 1;
|
27
|
+
hasCarryOver = false;
|
28
|
+
}],
|
29
|
+
]);
|
30
|
+
var mapInt = new Map([
|
31
|
+
[57, function () {
|
32
|
+
array[idx] = 48;
|
33
|
+
idx -= 1;
|
34
|
+
}],
|
35
|
+
[0, function () {
|
36
|
+
array[idx] += 1;
|
37
|
+
hasCarryOver = false;
|
38
|
+
}],
|
39
|
+
]);
|
40
|
+
while (hasCarryOver && idx >= 0) {
|
41
|
+
var map = isFloat ? mapFloat : mapInt;
|
42
|
+
var key = map.has(array[idx]) ? array[idx] : 0;
|
43
|
+
(_a = map.get(key)) === null || _a === void 0 ? void 0 : _a();
|
44
|
+
}
|
45
|
+
hasCarryOver && array.unshift(49);
|
46
|
+
return [array, isFloat];
|
47
|
+
};
|
48
|
+
export var calcLast = function (current, next, roundMode) {
|
49
|
+
var _a;
|
50
|
+
var isEven = current % 2 === 1;
|
51
|
+
var map = (_a = {},
|
52
|
+
_a[UP] = current + (next > 48 ? 1 : 0),
|
53
|
+
_a[DOWN] = current,
|
54
|
+
_a[HALF_UP] = current + (next >= 53 ? 1 : 0),
|
55
|
+
_a[HALF_DOWN] = current + (next > 53 ? 1 : 0),
|
56
|
+
_a[HALF_EVEN] = current + ((isEven && next >= 53) ? 1 : 0),
|
57
|
+
_a[HALF_ODD] = current + ((!isEven && next >= 53) ? 1 : 0),
|
58
|
+
_a);
|
59
|
+
return map[roundMode] > 57 ? [48, true] : [map[roundMode], false];
|
60
|
+
};
|
package/src/sub/index.d.ts
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
/** This function subtracts
|
1
|
+
/** This function subtracts numbers (as string). */
|
2
2
|
export declare function sub(strs: string[]): string;
|
package/src/sub/index.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import { addition } from "../add/utils.js";
|
2
2
|
import { a2sSA, s2aSA } from "../shared/utils.js";
|
3
3
|
import { subtract } from "./utils.js";
|
4
|
-
/** This function subtracts
|
4
|
+
/** This function subtracts numbers (as string). */
|
5
5
|
export function sub(strs) {
|
6
6
|
var arrays = strs.map(function (str) { return s2aSA(str); });
|
7
7
|
var inputData = arrays.reduce(function (left, right) {
|