@numio/bigmath 1.0.2 → 1.0.4
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 +128 -24
- package/index.d.ts +3 -1
- package/index.js +3 -1
- package/package.json +1 -1
- package/src/add/index.d.ts +1 -1
- package/src/add/index.js +5 -17
- package/src/add/utils.d.ts +2 -0
- package/src/add/utils.js +17 -6
- package/src/div/index.d.ts +1 -1
- package/src/div/index.js +5 -10
- package/src/div/utils.d.ts +2 -0
- package/src/div/utils.js +20 -7
- package/src/mul/index.d.ts +1 -1
- package/src/mul/index.js +5 -10
- package/src/mul/utils.d.ts +2 -0
- package/src/mul/utils.js +7 -0
- package/src/pipe/main.d.ts +13 -0
- package/src/pipe/main.js +35 -0
- 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/shared/constant.d.ts +6 -0
- package/src/shared/constant.js +6 -0
- package/src/shared/types.d.ts +2 -3
- package/src/shared/utils.d.ts +3 -5
- package/src/shared/utils.js +3 -47
- package/src/sub/index.d.ts +1 -1
- package/src/sub/index.js +5 -17
- package/src/sub/utils.d.ts +2 -0
- package/src/sub/utils.js +18 -13
package/README.md
CHANGED
@@ -1,37 +1,56 @@
|
|
1
1
|
# @numio/bigmath
|
2
2
|
|
3
|
-
@numio/bigmath is an arbitrary-precision arithmetic library. This library
|
4
|
-
|
3
|
+
@numio/bigmath is an arbitrary-precision arithmetic library. This library
|
4
|
+
provides functions for performing arithmetic operations (addition, subtraction,
|
5
|
+
multiplication, and division) on numbers of arbitrary length. It addresses the
|
6
|
+
limitations of JavaScript's built-in number type, which suffers from precision
|
7
|
+
loss when dealing with very large or very small numbers, or numbers with more
|
8
|
+
than 15 significant digits.
|
5
9
|
|
6
10
|
## Key Features and Benefits
|
7
11
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
- **Arbitrary Precision:** Handles numbers of any length, avoiding the
|
13
|
+
limitations of JavaScript's `Number` type. This allows for calculations with
|
14
|
+
extremely large or small numbers without loss of precision.
|
15
|
+
- **No Precision Loss:** Eliminates precision errors that occur when using
|
16
|
+
numeric literals with more than 15 significant digits. The library ensures
|
17
|
+
accurate calculations even with very long numbers.
|
18
|
+
- **Four Basic Operations:** Provides functions for addition (`add`),
|
19
|
+
subtraction (`sub`), multiplication (`mul`), and division (`div`).
|
20
|
+
- **Decimal Handling:** Correctly handles decimal numbers and performs
|
21
|
+
calculations accurately, including scenarios involving negative numbers.
|
22
|
+
- **Division Precision Control:** The `div` function allows you to specify the
|
23
|
+
number of digits after the decimal point for the result. The default precision
|
24
|
+
is 20 digits.
|
25
|
+
- **Easy to Use:** The library provides simple and intuitive functions for
|
26
|
+
performing arithmetic operations.
|
15
27
|
|
16
28
|
## How it Solves the Problem
|
17
29
|
|
18
|
-
JavaScript's `Number` type uses a 64-bit floating-point representation (IEEE
|
30
|
+
JavaScript's `Number` type uses a 64-bit floating-point representation (IEEE
|
31
|
+
754), which can lead to precision issues when dealing with numbers that exceed
|
32
|
+
its representable range or require more than 15 significant digits. This library
|
33
|
+
likely uses a different representation internally (e.g., strings or arrays of
|
34
|
+
digits) to store and manipulate numbers, effectively bypassing the limitations
|
35
|
+
of the built-in `Number` type. This allows it to perform calculations on numbers
|
36
|
+
of virtually unlimited size and maintain accuracy.
|
19
37
|
|
20
38
|
## Use Cases
|
21
39
|
|
22
|
-
This library is particularly useful in scenarios where precise calculations with
|
23
|
-
|
24
|
-
* **Financial applications:** Dealing with large sums of money or precise interest calculations.
|
25
|
-
* **Scientific computing:** Working with very large or small numbers in scientific simulations.
|
26
|
-
* **Cryptography:** Implementing cryptographic algorithms that require high precision.
|
27
|
-
* **Any application** where exceeding JavaScript's number limits is a concern.
|
40
|
+
This library is particularly useful in scenarios where precise calculations with
|
41
|
+
large numbers are essential, such as:
|
28
42
|
|
43
|
+
- **Financial applications:** Dealing with large sums of money or precise
|
44
|
+
interest calculations.
|
45
|
+
- **Scientific computing:** Working with very large or small numbers in
|
46
|
+
scientific simulations.
|
47
|
+
- **Cryptography:** Implementing cryptographic algorithms that require high
|
48
|
+
precision.
|
49
|
+
- **Any application** where exceeding JavaScript's number limits is a concern.
|
29
50
|
|
30
51
|
### Latest update
|
31
52
|
|
32
|
-
|
33
|
-
In version 0.3.0 added handling of negative numbers \
|
34
|
-
In version 0.2.0 added division (int & float numbers)
|
53
|
+
Added pipe functionality
|
35
54
|
|
36
55
|
# Install:
|
37
56
|
|
@@ -78,6 +97,7 @@ const negative = add(["0.1", "-0.3", "0.1"]); // -0.1
|
|
78
97
|
```
|
79
98
|
|
80
99
|
### Subtract numbers
|
100
|
+
|
81
101
|
```javascript
|
82
102
|
import { sub } from "@numio/bigmath";
|
83
103
|
|
@@ -87,6 +107,7 @@ const negative = sub(["-0.1", "-0.3", "0.4"]); // -0.2
|
|
87
107
|
```
|
88
108
|
|
89
109
|
### Multiply numbers
|
110
|
+
|
90
111
|
```javascript
|
91
112
|
import { mul } from "@numio/bigmath";
|
92
113
|
|
@@ -96,10 +117,11 @@ const negative = mul(["-2", "3"]); // -6
|
|
96
117
|
```
|
97
118
|
|
98
119
|
### Divide numbers
|
120
|
+
|
99
121
|
```javascript
|
100
122
|
import { div } from "@numio/bigmath";
|
101
123
|
|
102
|
-
const int = div(["9999", "33"]); //
|
124
|
+
const int = div(["9999", "33"]); //
|
103
125
|
const float = div(["0.06", "0.2"]); // 0.3
|
104
126
|
const negative = div(["-2", "-3", "2"]); // 3
|
105
127
|
|
@@ -107,6 +129,88 @@ const negative = div(["-2", "-3", "2"]); // 3
|
|
107
129
|
div("10", "3"); // 3.33333
|
108
130
|
```
|
109
131
|
|
132
|
+
### Round
|
133
|
+
|
134
|
+
```javascript
|
135
|
+
import { round } from "@numio/bigmath";
|
136
|
+
|
137
|
+
round("-1.12345"); // -1
|
138
|
+
round("1.5"); // 2
|
139
|
+
round("1.0"); // 1
|
140
|
+
round("0.00001"); // 0
|
141
|
+
round("9.9"); // 10
|
142
|
+
```
|
143
|
+
|
144
|
+
### Round at position
|
145
|
+
|
146
|
+
```javascript
|
147
|
+
import { round } from "@numio/bigmath";
|
148
|
+
|
149
|
+
round("1.12345", { decimals: 1 }); // 1.1
|
150
|
+
round("1.12345", { decimals: 2 }); // 1.12
|
151
|
+
round("1.12234", { decimals: 0 }); // 1
|
152
|
+
round("9.999", { decimals: 2 }); // 10
|
153
|
+
```
|
154
|
+
|
155
|
+
### Round modes
|
156
|
+
|
157
|
+
```javascript
|
158
|
+
import { round } from "@numio/bigmath";
|
159
|
+
|
160
|
+
round("1.11", { decimals: 1, roundMode: "up" }); // 1.2
|
161
|
+
round("1.19", { decimals: 1, roundMode: "up" }); // 1.2
|
162
|
+
|
163
|
+
round("1.11", { decimals: 1, roundMode: "down" }); // 1.1
|
164
|
+
round("1.19", { decimals: 1, roundMode: "down" }); // 1.1
|
165
|
+
|
166
|
+
round("1.15", { decimals: 1, roundMode: "half-up" }); // 1.2
|
167
|
+
round("1.15", { decimals: 1, roundMode: "half-down" }); // 1.1
|
168
|
+
|
169
|
+
round("1.15", { decimals: 1, roundMode: "half-even" }); // 1.2
|
170
|
+
round("1.25", { decimals: 1, roundMode: "half-even" }); // 1.2
|
171
|
+
round("1.35", { decimals: 1, roundMode: "half-even" }); // 1.4
|
172
|
+
round("1.45", { decimals: 1, roundMode: "half-even" }); // 1.4
|
173
|
+
round("1.55", { decimals: 1, roundMode: "half-even" }); // 1.6
|
174
|
+
|
175
|
+
round("1.15", { decimals: 1, roundMode: "half-odd" }); // 1.1
|
176
|
+
round("1.25", { decimals: 1, roundMode: "half-odd" }); // 1.3
|
177
|
+
round("1.35", { decimals: 1, roundMode: "half-odd" }); // 1.3
|
178
|
+
round("1.45", { decimals: 1, roundMode: "half-odd" }); // 1.5
|
179
|
+
round("1.55", { decimals: 1, roundMode: "half-odd" }); // 1.5
|
180
|
+
```
|
181
|
+
|
182
|
+
### Round with "significant figures" flag
|
183
|
+
|
184
|
+
```javascript
|
185
|
+
import { round } from "@numio/bigmath";
|
186
|
+
|
187
|
+
round("0.000119", { decimals: 2, sigFig: false }); // 0
|
188
|
+
round("0.000119", { decimals: 2, sigFig: true }); // 0.00012
|
189
|
+
|
190
|
+
round("0.0019", { decimals: 1, sigFig: true, roundMode: "down" }); // 0.001
|
191
|
+
round("0.0011", { decimals: 1, sigFig: true, roundMode: "up" }); // 0.002
|
192
|
+
|
193
|
+
round("1.000119", { decimals: 2, sigFig: false }); // 1
|
194
|
+
round("1.000119", { decimals: 2, sigFig: true }); // 1
|
195
|
+
```
|
196
|
+
|
197
|
+
### Pipe
|
198
|
+
|
199
|
+
```javascript
|
200
|
+
import { pipe } from "@numio/bigmath";
|
201
|
+
|
202
|
+
const addNums = ["1", "2", "3"];
|
203
|
+
const subNums = ["0.2", "0.3"];
|
204
|
+
const divNums = ["4"];
|
205
|
+
const mulNums = ["2", "5", "0.2"];
|
206
|
+
|
207
|
+
pipe.add(addNums) // 6
|
208
|
+
.div(divNums) // 6 / 4 = 1.5
|
209
|
+
.sub(subNums) // 1.5 - 0.2 - 0.3 = 1
|
210
|
+
.mul(mulNums) // 1 * 2 * 5 * 0.2 = 2
|
211
|
+
.calc()
|
212
|
+
```
|
213
|
+
|
110
214
|
Does not have a limitation on the number of digits. You can use any length you'd
|
111
215
|
like
|
112
216
|
|
@@ -123,7 +227,7 @@ const float = mul(
|
|
123
227
|
); // 0.00000000000000000000000000000000000000000000000000000000000000000000000000018
|
124
228
|
```
|
125
229
|
|
126
|
-
Download from NPM - https://www.npmjs.com/package/@numio/bigmath
|
127
|
-
Download from JSR - https://jsr.io/@numio/bigmath
|
128
|
-
Home page - https://github.com/shpunter/numio-bigmath/blob/main/README.md
|
129
|
-
License - https://github.com/shpunter/numio-bigmath/blob/main/LICENSE
|
230
|
+
Download from NPM - https://www.npmjs.com/package/@numio/bigmath\
|
231
|
+
Download from JSR - https://jsr.io/@numio/bigmath\
|
232
|
+
Home page - https://github.com/shpunter/numio-bigmath/blob/main/README.md\
|
233
|
+
License - https://github.com/shpunter/numio-bigmath/blob/main/LICENSE
|
package/index.d.ts
CHANGED
@@ -2,4 +2,6 @@ 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
|
+
import { pipe } from "./src/pipe/main.d.ts";
|
7
|
+
export { add, div, mul, round, sub, pipe };
|
package/index.js
CHANGED
@@ -2,4 +2,6 @@ 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
|
+
import { pipe } from "./src/pipe/main.js";
|
7
|
+
export { add, div, mul, round, sub, pipe };
|
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.4",
|
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,19 +1,7 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import {
|
4
|
-
/** This function adds
|
1
|
+
import { DEFAULT } from "../shared/constant.js";
|
2
|
+
import { a2s, s2a } from "../shared/utils.js";
|
3
|
+
import { addRoute } from "./utils.js";
|
4
|
+
/** This function adds numbers (as string). */
|
5
5
|
export function add(strs) {
|
6
|
-
|
7
|
-
var inputData = arrays.reduce(function (left, right) {
|
8
|
-
if (left.array.length === 0)
|
9
|
-
return right;
|
10
|
-
if (left.isNegative && !right.isNegative) {
|
11
|
-
return subtract([right.array, right.intLength], [left.array, left.intLength]);
|
12
|
-
}
|
13
|
-
if (!left.isNegative && right.isNegative) {
|
14
|
-
return subtract([left.array, left.intLength], [right.array, right.intLength]);
|
15
|
-
}
|
16
|
-
return addition([left.array, left.intLength], [right.array, right.intLength], left.isNegative && right.isNegative);
|
17
|
-
}, { array: [], intLength: 0, isFloat: false, isNegative: false });
|
18
|
-
return a2sSA(inputData.array, inputData.isFloat, inputData.isNegative);
|
6
|
+
return a2s(addRoute(strs.map(function (str) { return s2a(str); }), DEFAULT));
|
19
7
|
}
|
package/src/add/utils.d.ts
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
import type { InputData } from "../types.d.ts";
|
1
2
|
import type { Addition } from "./types.d.ts";
|
2
3
|
/** This function adds 2 numbers (as array). */
|
3
4
|
export declare const addition: Addition;
|
5
|
+
export declare const addRoute: (input: InputData[], initValue: InputData) => InputData;
|
package/src/add/utils.js
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import { subtract } from "../sub/utils.js";
|
1
2
|
/** This function adds 2 numbers (as array). */
|
2
3
|
export var addition = function (_a, _b, isNegative) {
|
3
4
|
var _c, _d;
|
@@ -12,13 +13,10 @@ export var addition = function (_a, _b, isNegative) {
|
|
12
13
|
var pl = (intLeft >= intRight ? intLeft : intRight) + fracMaxLen;
|
13
14
|
var pr = (intLeft >= intRight ? intRight : intLeft) + fracMaxLen;
|
14
15
|
var carryOver = 48;
|
15
|
-
|
16
|
-
left.push(
|
16
|
+
while (pl > left.length - 1) {
|
17
|
+
left.push(48);
|
18
|
+
}
|
17
19
|
while (pr >= 0) {
|
18
|
-
if (left[pl] === 46 || right[pr] === 46) {
|
19
|
-
pr -= 1;
|
20
|
-
pl -= 1;
|
21
|
-
}
|
22
20
|
var sum = (((_c = left[pl]) !== null && _c !== void 0 ? _c : 48) + ((_d = right[pr]) !== null && _d !== void 0 ? _d : 48) + carryOver) -
|
23
21
|
3 * 48;
|
24
22
|
if (sum > 9) {
|
@@ -46,3 +44,16 @@ export var addition = function (_a, _b, isNegative) {
|
|
46
44
|
isFloat: fracLenL + fracLenR > 0,
|
47
45
|
};
|
48
46
|
};
|
47
|
+
export var addRoute = function (input, initValue) {
|
48
|
+
return input.reduce(function (left, right) {
|
49
|
+
if (left.array.length === 0)
|
50
|
+
return right;
|
51
|
+
if (left.isNegative && !right.isNegative) {
|
52
|
+
return subtract([right.array, right.intLength], [left.array, left.intLength]);
|
53
|
+
}
|
54
|
+
if (!left.isNegative && right.isNegative) {
|
55
|
+
return subtract([left.array, left.intLength], [right.array, right.intLength]);
|
56
|
+
}
|
57
|
+
return addition([left.array, left.intLength], [right.array, right.intLength], left.isNegative && right.isNegative);
|
58
|
+
}, initValue);
|
59
|
+
};
|
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,15 +1,10 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
|
1
|
+
import { DEFAULT } from "../shared/constant.js";
|
2
|
+
import { a2s, s2a } from "../shared/utils.js";
|
3
|
+
import { divRoute } from "./utils.js";
|
4
|
+
/** This function should divide numbers (as string). */
|
4
5
|
export var div = function (strs, limit) {
|
5
6
|
if (limit === void 0) { limit = 20; }
|
6
7
|
if (strs[0] === "0")
|
7
8
|
return strs[0];
|
8
|
-
|
9
|
-
var inputData = arrays.reduce(function (left, right) {
|
10
|
-
if (left.array.length === 0)
|
11
|
-
return right;
|
12
|
-
return division([left.array, left.intLength], [right.array, right.intLength], left.isNegative !== right.isNegative, limit);
|
13
|
-
}, { array: [], intLength: 0, isNegative: false, isFloat: false });
|
14
|
-
return a2sMD(inputData.array, inputData.intLength != inputData.array.length, inputData.isNegative, inputData.intLength);
|
9
|
+
return a2s(divRoute(strs.map(function (str) { return s2a(str); }), DEFAULT, limit));
|
15
10
|
};
|
package/src/div/utils.d.ts
CHANGED
package/src/div/utils.js
CHANGED
@@ -80,11 +80,24 @@ export var division = function (_a, _b, isNegative, initLimit) {
|
|
80
80
|
intLength -= 1;
|
81
81
|
}
|
82
82
|
}
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
83
|
+
return result.length === count
|
84
|
+
? {
|
85
|
+
array: [48],
|
86
|
+
isFloat: false,
|
87
|
+
isNegative: false,
|
88
|
+
intLength: 1,
|
89
|
+
}
|
90
|
+
: {
|
91
|
+
array: result[0] === 48 ? multipliedResult : result,
|
92
|
+
isFloat: isFloat,
|
93
|
+
isNegative: isNegative,
|
94
|
+
intLength: intLength,
|
95
|
+
};
|
96
|
+
};
|
97
|
+
export var divRoute = function (input, initValue, limit) {
|
98
|
+
return input.reduce(function (left, right) {
|
99
|
+
if (left.array.length === 0)
|
100
|
+
return right;
|
101
|
+
return division([left.array, left.intLength], [right.array, right.intLength], left.isNegative !== right.isNegative, limit);
|
102
|
+
}, initValue);
|
90
103
|
};
|
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,12 +1,7 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
|
1
|
+
import { DEFAULT } from "../shared/constant.js";
|
2
|
+
import { a2s, s2a } from "../shared/utils.js";
|
3
|
+
import { mulRoute } from "./utils.js";
|
4
|
+
/** This function multiplies numbers (as string). */
|
4
5
|
export var mul = function (strs) {
|
5
|
-
|
6
|
-
var inputData = arrays.reduce(function (left, right) {
|
7
|
-
if (left.array.length === 0)
|
8
|
-
return right;
|
9
|
-
return multiplication([left.array, left.intLength], [right.array, right.intLength], left.isNegative !== right.isNegative);
|
10
|
-
}, { array: [], intLength: 0, isNegative: false, isFloat: false });
|
11
|
-
return a2sMD(inputData.array, inputData.intLength != inputData.array.length, inputData.isNegative, inputData.intLength);
|
6
|
+
return a2s(mulRoute(strs.map(function (str) { return s2a(str); }), DEFAULT));
|
12
7
|
};
|
package/src/mul/utils.d.ts
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
import type { InputData } from "../types.d.ts";
|
1
2
|
import type { Multiplication } from "./types.d.ts";
|
2
3
|
/** This function multiplies 2 numbers (as array). */
|
3
4
|
export declare const multiplication: Multiplication;
|
5
|
+
export declare const mulRoute: (input: InputData[], initValue: InputData) => InputData;
|
package/src/mul/utils.js
CHANGED
@@ -40,3 +40,10 @@ export var multiplication = function (_a, _b, isNegative) {
|
|
40
40
|
isNegative: isNegative,
|
41
41
|
};
|
42
42
|
};
|
43
|
+
export var mulRoute = function (input, initValue) {
|
44
|
+
return input.reduce(function (left, right) {
|
45
|
+
if (left.array.length === 0)
|
46
|
+
return right;
|
47
|
+
return multiplication([left.array, left.intLength], [right.array, right.intLength], left.isNegative !== right.isNegative);
|
48
|
+
}, initValue);
|
49
|
+
};
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import type { A2S } from "../shared/types.d.ts";
|
2
|
+
import type { InputData } from "../types.d.ts";
|
3
|
+
declare class Pipe {
|
4
|
+
result: InputData;
|
5
|
+
constructor();
|
6
|
+
add(strs: string[]): Pipe;
|
7
|
+
sub(strs: string[]): Pipe;
|
8
|
+
div(strs: string[], limit?: number): Pipe;
|
9
|
+
mul(strs: string[]): Pipe;
|
10
|
+
calc(): ReturnType<A2S>;
|
11
|
+
}
|
12
|
+
export declare const pipe: Pipe;
|
13
|
+
export {};
|
package/src/pipe/main.js
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
import { addRoute } from "../add/utils.js";
|
2
|
+
import { divRoute } from "../div/utils.js";
|
3
|
+
import { mulRoute } from "../mul/utils.js";
|
4
|
+
import { DEFAULT } from "../shared/constant.js";
|
5
|
+
import { a2s, s2a } from "../shared/utils.js";
|
6
|
+
import { subRoute } from "../sub/utils.js";
|
7
|
+
var Pipe = /** @class */ (function () {
|
8
|
+
function Pipe() {
|
9
|
+
this.result = DEFAULT;
|
10
|
+
}
|
11
|
+
Pipe.prototype.add = function (strs) {
|
12
|
+
this.result = addRoute(strs.map(function (str) { return s2a(str); }), this.result);
|
13
|
+
return this;
|
14
|
+
};
|
15
|
+
Pipe.prototype.sub = function (strs) {
|
16
|
+
this.result = subRoute(strs.map(function (str) { return s2a(str); }), this.result);
|
17
|
+
return this;
|
18
|
+
};
|
19
|
+
Pipe.prototype.div = function (strs, limit) {
|
20
|
+
if (limit === void 0) { limit = 20; }
|
21
|
+
this.result = divRoute(strs.map(function (str) { return s2a(str); }), this.result, limit);
|
22
|
+
return this;
|
23
|
+
};
|
24
|
+
Pipe.prototype.mul = function (strs) {
|
25
|
+
this.result = mulRoute(strs.map(function (str) { return s2a(str); }), this.result);
|
26
|
+
return this;
|
27
|
+
};
|
28
|
+
Pipe.prototype.calc = function () {
|
29
|
+
var result = a2s(this.result);
|
30
|
+
this.result = DEFAULT;
|
31
|
+
return result;
|
32
|
+
};
|
33
|
+
return Pipe;
|
34
|
+
}());
|
35
|
+
export var pipe = new Pipe();
|
@@ -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/shared/types.d.ts
CHANGED
@@ -1,4 +1,3 @@
|
|
1
1
|
import type { InputData } from "../types.d.ts";
|
2
|
-
export type A2S = (
|
3
|
-
export type
|
4
|
-
export type S2AMD = (strings: string) => InputData;
|
2
|
+
export type A2S = (input: InputData) => string;
|
3
|
+
export type S2A = (strings: string) => InputData;
|
package/src/shared/utils.d.ts
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
import type { A2S,
|
2
|
-
export declare const
|
3
|
-
export declare const
|
4
|
-
export declare const s2aSA: S2ASA;
|
5
|
-
export declare const s2aMD: S2AMD;
|
1
|
+
import type { A2S, S2A } from "./types.d.ts";
|
2
|
+
export declare const a2s: A2S;
|
3
|
+
export declare const s2a: S2A;
|
package/src/shared/utils.js
CHANGED
@@ -1,7 +1,5 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
if (isNegative === void 0) { isNegative = false; }
|
4
|
-
if (intLength === void 0) { intLength = 0; }
|
1
|
+
export var a2s = function (_a) {
|
2
|
+
var array = _a.array, isFloat = _a.isFloat, isNegative = _a.isNegative, intLength = _a.intLength;
|
5
3
|
var result = [];
|
6
4
|
var lastValuableIdx = array.length;
|
7
5
|
if (isFloat) {
|
@@ -32,49 +30,7 @@ export var a2sMD = function (array, isFloat, isNegative, intLength) {
|
|
32
30
|
}
|
33
31
|
return (isNegative ? "-" : "") + String.fromCharCode.apply(String, array).trim();
|
34
32
|
};
|
35
|
-
export var
|
36
|
-
if (isNegative === void 0) { isNegative = false; }
|
37
|
-
var isToCheckTail = isFloat;
|
38
|
-
for (var i = array.length - 1; i >= 0; i--) {
|
39
|
-
if (isToCheckTail && array[i] === 46) {
|
40
|
-
array[i] = 32;
|
41
|
-
isToCheckTail = false;
|
42
|
-
break;
|
43
|
-
}
|
44
|
-
if (isToCheckTail && array[i] === 48)
|
45
|
-
array[i] = 32;
|
46
|
-
else
|
47
|
-
break;
|
48
|
-
}
|
49
|
-
for (var i = 0; i < array.length; i++) {
|
50
|
-
if (array[i + 1] === 46 || array.length <= 1)
|
51
|
-
break;
|
52
|
-
if (array[i] === 48)
|
53
|
-
array[i] = 32;
|
54
|
-
else
|
55
|
-
break;
|
56
|
-
}
|
57
|
-
return (isNegative ? "-" : "") + String.fromCharCode.apply(String, array).trim();
|
58
|
-
};
|
59
|
-
// string to array (sub, add)
|
60
|
-
export var s2aSA = function (string) {
|
61
|
-
var isNegative = string.charCodeAt(0) === 45;
|
62
|
-
var shift = isNegative ? 1 : 0;
|
63
|
-
var array = Array(string.length - shift);
|
64
|
-
var intLength = string.length - shift;
|
65
|
-
var isFloat = false;
|
66
|
-
for (var idx = 0 + shift; idx < string.length; idx++) {
|
67
|
-
var charCode = string.charCodeAt(idx);
|
68
|
-
if (charCode === 46) {
|
69
|
-
intLength = idx - shift;
|
70
|
-
isFloat || (isFloat = true);
|
71
|
-
}
|
72
|
-
array[idx - shift] = charCode;
|
73
|
-
}
|
74
|
-
return { array: array, intLength: intLength, isNegative: isNegative, isFloat: isFloat };
|
75
|
-
};
|
76
|
-
// string to array (mul, div)
|
77
|
-
export var s2aMD = function (string) {
|
33
|
+
export var s2a = function (string) {
|
78
34
|
var array = Array(0);
|
79
35
|
var isNegative = string.charCodeAt(0) === 45;
|
80
36
|
var shift = isNegative ? 1 : 0;
|
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,19 +1,7 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import {
|
4
|
-
/** This function subtracts
|
1
|
+
import { DEFAULT } from "../shared/constant.js";
|
2
|
+
import { a2s, s2a } from "../shared/utils.js";
|
3
|
+
import { subRoute } from "./utils.js";
|
4
|
+
/** This function subtracts numbers (as string). */
|
5
5
|
export function sub(strs) {
|
6
|
-
|
7
|
-
var inputData = arrays.reduce(function (left, right) {
|
8
|
-
if (left.array.length === 0)
|
9
|
-
return right;
|
10
|
-
if (left.isNegative && right.isNegative) {
|
11
|
-
return subtract([right.array, right.intLength], [left.array, left.intLength]);
|
12
|
-
}
|
13
|
-
if (!left.isNegative && !right.isNegative) {
|
14
|
-
return subtract([left.array, left.intLength], [right.array, right.intLength]);
|
15
|
-
}
|
16
|
-
return addition([left.array, left.intLength], [right.array, right.intLength], left.isNegative);
|
17
|
-
}, { array: [], intLength: 0, isNegative: false, isFloat: false });
|
18
|
-
return a2sSA(inputData.array, inputData.isFloat, inputData.isNegative);
|
6
|
+
return a2s(subRoute(strs.map(function (str) { return s2a(str); }), DEFAULT));
|
19
7
|
}
|
package/src/sub/utils.d.ts
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
import type { InputData } from "../types.d.ts";
|
1
2
|
import type { Subtract } from "./types.d.ts";
|
2
3
|
/** This function subtracts 2 numbers (as array). */
|
3
4
|
export declare const subtract: Subtract;
|
5
|
+
export declare const subRoute: (input: InputData[], initValue: InputData) => InputData;
|
package/src/sub/utils.js
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import { addition } from "../add/utils.js";
|
1
2
|
/** This function subtracts 2 numbers (as array). */
|
2
3
|
export var subtract = function (_a, _b) {
|
3
4
|
var _c, _d;
|
@@ -15,15 +16,10 @@ export var subtract = function (_a, _b) {
|
|
15
16
|
var isLeftBigger = lenDiff > 0;
|
16
17
|
var carryOver = false;
|
17
18
|
var isNegative = intLeft !== intL;
|
18
|
-
|
19
|
-
left.push(
|
20
|
-
|
21
|
-
right.push(46);
|
19
|
+
while (pl > left.length - 1) {
|
20
|
+
left.push(48);
|
21
|
+
}
|
22
22
|
while (pr < right.length) {
|
23
|
-
if (left[pl] === 46 || right[pr] === 46) {
|
24
|
-
pr += 1;
|
25
|
-
pl += 1;
|
26
|
-
}
|
27
23
|
var sub = (((_e = left[pl]) !== null && _e !== void 0 ? _e : 48) - ((_f = right[pr]) !== null && _f !== void 0 ? _f : 48)) + 48;
|
28
24
|
if (!isLeftBigger && left[pl] > right[pr]) {
|
29
25
|
isLeftBigger = true;
|
@@ -42,10 +38,6 @@ export var subtract = function (_a, _b) {
|
|
42
38
|
var plReverse = pl - 1;
|
43
39
|
var prReverse = pr - 1;
|
44
40
|
while (carryOver) {
|
45
|
-
if (left[plReverse] === 46 || right[prReverse] === 46) {
|
46
|
-
plReverse -= 1;
|
47
|
-
prReverse -= 1;
|
48
|
-
}
|
49
41
|
if (left[plReverse] !== 48) {
|
50
42
|
plReverse >= 0 && (left[plReverse] -= 1);
|
51
43
|
prReverse >= 0 && (right[prReverse] -= 1);
|
@@ -63,7 +55,7 @@ export var subtract = function (_a, _b) {
|
|
63
55
|
pl += 1;
|
64
56
|
pr += 1;
|
65
57
|
}
|
66
|
-
while (left[0] === 48 && left
|
58
|
+
while (left[0] === 48 && left.length > 1 && fracLenL < left.length - 1) {
|
67
59
|
left.shift();
|
68
60
|
intLeft -= 1;
|
69
61
|
}
|
@@ -74,3 +66,16 @@ export var subtract = function (_a, _b) {
|
|
74
66
|
isFloat: fracLenL + fracLenR > 0,
|
75
67
|
};
|
76
68
|
};
|
69
|
+
export var subRoute = function (input, initValue) {
|
70
|
+
return input.reduce(function (left, right) {
|
71
|
+
if (left.array.length === 0)
|
72
|
+
return right;
|
73
|
+
if (left.isNegative && right.isNegative) {
|
74
|
+
return subtract([right.array, right.intLength], [left.array, left.intLength]);
|
75
|
+
}
|
76
|
+
if (!left.isNegative && !right.isNegative) {
|
77
|
+
return subtract([left.array, left.intLength], [right.array, right.intLength]);
|
78
|
+
}
|
79
|
+
return addition([left.array, left.intLength], [right.array, right.intLength], left.isNegative);
|
80
|
+
}, initValue);
|
81
|
+
};
|