@numio/bigmath 2.2.7 → 2.3.1
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/CHANGELOG.md +8 -0
- package/README.md +49 -63
- package/index.d.ts +2 -1
- package/index.js +2 -1
- package/package.json +4 -2
- package/src/FDR/fdr.d.ts +2 -0
- package/src/FDR/fdr.js +18 -0
- package/src/FDR/types.d.ts +21 -0
- package/src/FDR/utils.d.ts +2 -0
- package/src/FDR/utils.js +34 -0
- package/src/IQR/iqr.js +6 -3
- package/src/IQR/types.d.ts +2 -2
- package/src/IQR/utils.d.ts +0 -1
- package/src/IQR/utils.js +2 -12
- package/src/MAD/mad.js +6 -3
- package/src/MAD/types.d.ts +7 -2
- package/src/MAD/utils.js +7 -4
- package/src/cbrt/utils.js +4 -7
- package/src/compare/max.js +5 -1
- package/src/compare/min.js +5 -1
- package/src/compare/utils.js +5 -4
- package/src/mean/mean.js +4 -1
- package/src/mean/utils.js +5 -3
- package/src/operations/add/add.js +6 -6
- package/src/operations/div/div.d.ts +1 -1
- package/src/operations/div/div.js +6 -3
- package/src/operations/div/types.d.ts +1 -1
- package/src/operations/div/utils.js +5 -4
- package/src/operations/mul/mul.js +4 -1
- package/src/operations/sub/sub.js +4 -1
- package/src/pipe/pipe.d.ts +1 -1
- package/src/pipe/pipe.js +2 -2
- package/src/pipe/utils.d.ts +3 -2
- package/src/pipe/utils.js +9 -5
- package/src/quartile/quartile.js +4 -1
- package/src/quartile/utils.js +2 -2
- package/src/shared/types.d.ts +0 -1
- package/src/shared/utils.d.ts +3 -2
- package/src/shared/utils.js +24 -25
- package/src/sort/sort.js +4 -1
- package/src/sqrt/utils.js +4 -7
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
@@ -1,68 +1,54 @@
|
|
1
1
|
# @numio/bigmath: Precise Arithmetic Beyond JavaScript's Limits
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
* **Low-Level Operations:** Working with different number representations commonly found in computer systems.
|
53
|
-
* **Any Scenario Exceeding JavaScript's Number Limits:** Ensuring the reliability of your calculations when dealing with numbers beyond the safe integer limit or requiring more than 15 significant digits.
|
54
|
-
|
55
|
-
With `@numio/bigmath`, you can confidently perform complex arithmetic operations with the assurance of accuracy, regardless of the size or precision of the numbers involved.
|
56
|
-
|
57
|
-
### Latest update
|
58
|
-
|
59
|
-
**New Functions added:**
|
60
|
-
|
61
|
-
* `isHex` - Checks if a string is a valid hexadecimal number (prefixed with `0x` or `-0x`).
|
62
|
-
* `isBinary` - Checks if a string is a valid binary number (prefixed with `0b` or `-0b`).
|
63
|
-
* `isDecimal` - Checks if a string is a valid decimal number.
|
64
|
-
* `isOctal` - Checks if a string is a valid octal number (prefixed with `0o` or `-0o`).
|
65
|
-
* `isNumber` - Checks if a string is a valid number in any of the formats supported by the library (decimal, hexadecimal, binary, octal).
|
3
|
+
@numio/bigmath is a powerful and reliable JavaScript library designed for precise numerical computations, overcoming common limitations of standard JavaScript number handling. It provides a rich set of functionalities for arithmetic, statistical analysis, data manipulation, and number base conversions, ensuring accuracy even with extremely large numbers and solving notorious floating-point precision issues like `0.1 + 0.2 !== 0.3`.
|
4
|
+
|
5
|
+
|
6
|
+
## Latest Update
|
7
|
+
|
8
|
+
This update introduces several enhancements and new functionalities:
|
9
|
+
|
10
|
+
- **Improved Error Handling:** The application now features more robust error handling to provide clearer feedback and prevent unexpected crashes.
|
11
|
+
- **Freedman-Diaconis Rule (FDR):** Added the Freedman-Diaconis rule for optimal binwidth estimation in histogram creation.
|
12
|
+
- **Median Absolute Deviation (MAD):** Implemented calculation for the Median Absolute Deviation, allowing users to compute it based on either the `median` or the `mean` of the dataset.
|
13
|
+
|
14
|
+
## Existing Functionality
|
15
|
+
|
16
|
+
The application currently supports the following operations:
|
17
|
+
|
18
|
+
- **Arithmetic:**
|
19
|
+
- `add`: Addition of numbers.
|
20
|
+
- `sub`: Subtraction of numbers.
|
21
|
+
- `mul`: Multiplication of numbers.
|
22
|
+
- `div`: Division of numbers.
|
23
|
+
- **Rounding:**
|
24
|
+
- `round`: Rounding numbers to a specified number of decimal places.
|
25
|
+
- **Data Manipulation:**
|
26
|
+
- `pipe`: Chaining operations together.
|
27
|
+
- `sort`: Sorting arrays.
|
28
|
+
- **Statistical Measures:**
|
29
|
+
- `quartile`: Calculating quartiles of a dataset.
|
30
|
+
- `mean`: Calculating the average of a dataset.
|
31
|
+
- `max`: Finding the maximum value in a dataset.
|
32
|
+
- `min`: Finding the minimum value in a dataset.
|
33
|
+
- `MAD`: Calculating the Median Absolute Deviation (based on either median or mean).
|
34
|
+
- `IQR`: Calculating the Interquartile Range.
|
35
|
+
- **Comparison:**
|
36
|
+
- `isEqual`: Checking if two values are equal.
|
37
|
+
- `isLeftGreater`: Checking if the left value is greater than the right value.
|
38
|
+
- `isLeftGreaterOrEqual`: Checking if the left value is greater than or equal to the right value.
|
39
|
+
- **Mathematical Functions:**
|
40
|
+
- `sqrt`: Calculating the square root of a number.
|
41
|
+
- `cbrt`: Calculating the cube root of a number.
|
42
|
+
- `abs`: Calculating the absolute value of a number.
|
43
|
+
- **Number Base Conversion:**
|
44
|
+
- `toBase`: Converting a number to a specified base.
|
45
|
+
- `isHex`: Checking if a string is a valid hexadecimal number.
|
46
|
+
- `isBinary`: Checking if a string is a valid binary number.
|
47
|
+
- `isDecimal`: Checking if a string is a valid decimal number.
|
48
|
+
- `isOctal`: Checking if a string is a valid octal number.
|
49
|
+
- `isNumber`: Checking if a value is a number.
|
50
|
+
- **Utility:**
|
51
|
+
- `Benchmark`: Functionality for benchmarking code execution.
|
66
52
|
|
67
53
|
# Install:
|
68
54
|
|
package/index.d.ts
CHANGED
@@ -23,4 +23,5 @@ import { isBinary } from "./src/isValid/isBinary.d.ts";
|
|
23
23
|
import { isDecimal } from "./src/isValid/isDecimal.d.ts";
|
24
24
|
import { isOctal } from "./src/isValid/isOctal.d.ts";
|
25
25
|
import { isNumber } from "./src/isValid/isNumber.d.ts";
|
26
|
-
|
26
|
+
import { FDR } from "./src/FDR/fdr.d.ts";
|
27
|
+
export { abs, add, cbrt, div, IQR, isEqual, isLeftGreater, isLeftGreaterOrEqual, MAD, max, mean, min, mul, Pipe, quartile, round, sort, sqrt, sub, toBase, isHex, isBinary, isDecimal, isOctal, isNumber, FDR };
|
package/index.js
CHANGED
@@ -23,4 +23,5 @@ import { isBinary } from "./src/isValid/isBinary.js";
|
|
23
23
|
import { isDecimal } from "./src/isValid/isDecimal.js";
|
24
24
|
import { isOctal } from "./src/isValid/isOctal.js";
|
25
25
|
import { isNumber } from "./src/isValid/isNumber.js";
|
26
|
-
|
26
|
+
import { FDR } from "./src/FDR/fdr.js";
|
27
|
+
export { abs, add, cbrt, div, IQR, isEqual, isLeftGreater, isLeftGreaterOrEqual, MAD, max, mean, min, mul, Pipe, quartile, round, sort, sqrt, sub, toBase, isHex, isBinary, isDecimal, isOctal, isNumber, FDR };
|
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": "2.
|
4
|
+
"version": "2.3.1",
|
5
5
|
"keywords": [
|
6
6
|
"precision",
|
7
7
|
"arithmetic",
|
@@ -52,7 +52,9 @@
|
|
52
52
|
"binary",
|
53
53
|
"decimal",
|
54
54
|
"binary",
|
55
|
-
"cube root"
|
55
|
+
"cube root",
|
56
|
+
"FDR",
|
57
|
+
"Freedman-Diaconis Rule"
|
56
58
|
],
|
57
59
|
"repository": {
|
58
60
|
"type": "git",
|
package/src/FDR/fdr.d.ts
ADDED
package/src/FDR/fdr.js
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
import { bi2s, s2bi } from "../shared/utils.js";
|
2
|
+
import { fdrInner } from "./utils.js";
|
3
|
+
export const FDR = (array, options) => {
|
4
|
+
var _a, _b, _c;
|
5
|
+
const arrayInner = Array(array.length);
|
6
|
+
for (let i = 0; i < array.length; i++) {
|
7
|
+
arrayInner[i] = s2bi(array[i]);
|
8
|
+
}
|
9
|
+
const { binWidth, binsNum } = fdrInner(arrayInner, {
|
10
|
+
useMadAbove: (_a = options === null || options === void 0 ? void 0 : options.useMadAbove) !== null && _a !== void 0 ? _a : 0,
|
11
|
+
maxBinNumber: (_b = options === null || options === void 0 ? void 0 : options.maxBinNumber) !== null && _b !== void 0 ? _b : 90,
|
12
|
+
madFrom: (_c = options === null || options === void 0 ? void 0 : options.madFrom) !== null && _c !== void 0 ? _c : "median",
|
13
|
+
});
|
14
|
+
return {
|
15
|
+
binsNum: bi2s(binsNum),
|
16
|
+
binWidth: bi2s(binWidth),
|
17
|
+
};
|
18
|
+
};
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import type { MADFrom } from "../MAD/types.d.ts";
|
2
|
+
import type { BI } from "../shared/types.d.ts";
|
3
|
+
type Options = {
|
4
|
+
useMadAbove?: number;
|
5
|
+
maxBinNumber?: number;
|
6
|
+
madFrom?: MADFrom;
|
7
|
+
};
|
8
|
+
type OptionsInner = {
|
9
|
+
useMadAbove: number;
|
10
|
+
maxBinNumber: number;
|
11
|
+
madFrom: MADFrom;
|
12
|
+
};
|
13
|
+
export type FDRInner = (array: BI[], options: OptionsInner) => {
|
14
|
+
binWidth: BI;
|
15
|
+
binsNum: BI;
|
16
|
+
};
|
17
|
+
export type TFDR = (array: string[], options?: Options) => {
|
18
|
+
binWidth: string;
|
19
|
+
binsNum: string;
|
20
|
+
};
|
21
|
+
export {};
|
package/src/FDR/utils.js
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
import { cbrtInner } from "../cbrt/utils.js";
|
2
|
+
import { isLeftGreaterOrEqualInner } from "../compare/utils.js";
|
3
|
+
import { IQRInner } from "../IQR/utils.js";
|
4
|
+
import { MADInner } from "../MAD/utils.js";
|
5
|
+
import { divInner } from "../operations/div/utils.js";
|
6
|
+
import { PipeInner } from "../pipe/utils.js";
|
7
|
+
import { tryBigInt } from "../shared/utils.js";
|
8
|
+
const getBinsNum = (range, binWidth) => {
|
9
|
+
let binsNum = new PipeInner().div([range, binWidth], 10).bi;
|
10
|
+
if (binsNum[1] > 0) {
|
11
|
+
binsNum = [new PipeInner().div([range, binWidth], 0).bi[0] + 1n, 0];
|
12
|
+
}
|
13
|
+
return binsNum;
|
14
|
+
};
|
15
|
+
export const fdrInner = (array, options = { useMadAbove: 0, maxBinNumber: 90, madFrom: "mean" }) => {
|
16
|
+
const mad = MADInner(array, { from: options.madFrom });
|
17
|
+
const nonNilMad = mad[0] <= 0n ? [1n, 0] : mad;
|
18
|
+
const IQR = IQRInner(array);
|
19
|
+
const isMadUsed = array.length < options.useMadAbove || IQR[0] === 0n;
|
20
|
+
const validIQR = isMadUsed ? nonNilMad : IQR;
|
21
|
+
const [cbrtLen] = cbrtInner([tryBigInt(array.length), 0]);
|
22
|
+
const binWidth = new PipeInner().mul([[2n, 0], validIQR]).div([cbrtLen]).bi;
|
23
|
+
const range = new PipeInner().sub([array[array.length - 1], array[0]]).bi;
|
24
|
+
const binsNum = getBinsNum(range, binWidth);
|
25
|
+
const maxBinNum = [tryBigInt(options.maxBinNumber), 0];
|
26
|
+
const scale = isLeftGreaterOrEqualInner({ left: binsNum, right: maxBinNum })
|
27
|
+
? divInner([binsNum, maxBinNum], 20)
|
28
|
+
: [1n, 0];
|
29
|
+
const scaledBinWidth = new PipeInner().mul([binWidth, scale]).bi;
|
30
|
+
return {
|
31
|
+
binWidth: scaledBinWidth,
|
32
|
+
binsNum: getBinsNum(range, scaledBinWidth),
|
33
|
+
};
|
34
|
+
};
|
package/src/IQR/iqr.js
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
import { bi2s, s2bi } from "../shared/utils.js";
|
2
2
|
import { IQRInner } from "./utils.js";
|
3
3
|
//** This function returns Interquartile Range */
|
4
|
-
export const IQR = (array
|
5
|
-
const arrayInner = array.
|
6
|
-
|
4
|
+
export const IQR = (array) => {
|
5
|
+
const arrayInner = Array(array.length);
|
6
|
+
for (let i = 0; i < array.length; i++) {
|
7
|
+
arrayInner[i] = s2bi(array[i]);
|
8
|
+
}
|
9
|
+
const bi = IQRInner(arrayInner);
|
7
10
|
return bi2s(bi);
|
8
11
|
};
|
package/src/IQR/types.d.ts
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
import type { BI } from "../shared/types.d.ts";
|
2
|
-
export type TIQR = (array: string[]
|
3
|
-
export type TIQRInner = (array: BI[]
|
2
|
+
export type TIQR = (array: string[]) => string;
|
3
|
+
export type TIQRInner = (array: BI[]) => BI;
|
package/src/IQR/utils.d.ts
CHANGED
package/src/IQR/utils.js
CHANGED
@@ -1,20 +1,10 @@
|
|
1
|
-
import { isEqualInner } from "../compare/utils.js";
|
2
|
-
import { MADInner } from "../MAD/utils.js";
|
3
1
|
import { PipeInner } from "../pipe/utils.js";
|
4
2
|
import { quartileInner } from "../quartile/utils.js";
|
5
|
-
export const
|
6
|
-
export const IQRInner = (array, sigNum = false) => {
|
3
|
+
export const IQRInner = (array) => {
|
7
4
|
if (array.length < 3) {
|
8
5
|
throw Error("To calculate IQR you need at least 3 elements");
|
9
6
|
}
|
10
7
|
const { Q1, Q3 } = quartileInner(array);
|
11
|
-
const sub = new PipeInner().sub([Q3, Q1])
|
12
|
-
if (sigNum) {
|
13
|
-
const isEqual = isEqualInner({ left: Q3, right: Q1 });
|
14
|
-
const MAD = MADInner(array);
|
15
|
-
const isNil = isEqualInner({ left: MAD, right: [0n, 0] });
|
16
|
-
const nonNilMAD = isNil ? [1n, 0] : MAD;
|
17
|
-
return isEqual ? nonNilMAD : sub;
|
18
|
-
}
|
8
|
+
const { bi: sub } = new PipeInner().sub([Q3, Q1]);
|
19
9
|
return sub;
|
20
10
|
};
|
package/src/MAD/mad.js
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
import { bi2s, s2bi } from "../shared/utils.js";
|
2
2
|
import { MADInner } from "./utils.js";
|
3
3
|
//** This function returns Median Absolute Deviation */
|
4
|
-
export const MAD = (array) => {
|
5
|
-
const arrayInner = array.
|
6
|
-
|
4
|
+
export const MAD = (array, options = { from: "median" }) => {
|
5
|
+
const arrayInner = Array(array.length);
|
6
|
+
for (let i = 0; i < array.length; i++) {
|
7
|
+
arrayInner[i] = s2bi(array[i]);
|
8
|
+
}
|
9
|
+
const bi = MADInner(arrayInner, options);
|
7
10
|
return bi2s(bi);
|
8
11
|
};
|
package/src/MAD/types.d.ts
CHANGED
@@ -1,3 +1,8 @@
|
|
1
1
|
import type { BI } from "../shared/types.d.ts";
|
2
|
-
export type
|
3
|
-
|
2
|
+
export type MADFrom = "mean" | "median";
|
3
|
+
type Options = {
|
4
|
+
from: MADFrom;
|
5
|
+
};
|
6
|
+
export type TMAD = (array: string[], options?: Options) => string;
|
7
|
+
export type TMADInner = (array: BI[], options: Options) => BI;
|
8
|
+
export {};
|
package/src/MAD/utils.js
CHANGED
@@ -1,15 +1,18 @@
|
|
1
|
+
import { meanInner } from "../mean/utils.js";
|
1
2
|
import { PipeInner } from "../pipe/utils.js";
|
2
3
|
import { quartileInner } from "../quartile/utils.js";
|
3
4
|
import { ASC } from "../sort/constants.js";
|
4
5
|
import { sortInner } from "../sort/utils.js";
|
5
|
-
export const MADInner = (array) => {
|
6
|
+
export const MADInner = (array, { from }) => {
|
6
7
|
if (array.length < 3) {
|
7
8
|
throw Error("To calculate MAD you need at least 3 elements");
|
8
9
|
}
|
9
|
-
const
|
10
|
+
const fromMap = {
|
11
|
+
median: quartileInner(array).Q2,
|
12
|
+
mean: meanInner(array)
|
13
|
+
};
|
10
14
|
const madArray = array.map((el) => {
|
11
|
-
|
12
|
-
return bi < 0n ? [bi * -1n, fpe] : [bi, fpe];
|
15
|
+
return new PipeInner().sub([el, fromMap[from]]).abs().bi;
|
13
16
|
});
|
14
17
|
const sorted = sortInner(madArray, ASC);
|
15
18
|
return quartileInner(sorted).Q2;
|
package/src/cbrt/utils.js
CHANGED
@@ -3,21 +3,18 @@ import { divInner } from "../operations/div/utils.js";
|
|
3
3
|
import { PipeInner } from "../pipe/utils.js";
|
4
4
|
import { calcInner } from "../shared/utils.js";
|
5
5
|
export const cbrtInner = (value, prec = [1n, 13], max = 100) => {
|
6
|
-
var _a, _b;
|
7
6
|
if (value[0] < 0n) {
|
8
7
|
throw new Error("Invalid input: Cannot take the cube root of a negative value.");
|
9
8
|
}
|
10
9
|
let guess = value;
|
11
10
|
for (let i = 0; i < max; i++) {
|
12
11
|
const mul = calcInner([guess, guess], (a, b) => a * b);
|
13
|
-
const nextGuess
|
12
|
+
const { bi: nextGuess } = new PipeInner().add([
|
14
13
|
calcInner([guess, [2n, 0]], (a, b) => a * b),
|
15
14
|
divInner([value, mul], 20),
|
16
|
-
]).div([[3n, 0]])
|
17
|
-
|
18
|
-
if (bi
|
19
|
-
bi *= -1n;
|
20
|
-
if (isLeftGreaterInner({ left: prec, right: [bi, fpe] })) {
|
15
|
+
]).div([[3n, 0]]);
|
16
|
+
const { bi } = new PipeInner().sub([nextGuess, guess]).abs();
|
17
|
+
if (isLeftGreaterInner({ left: prec, right: bi })) {
|
21
18
|
return [nextGuess, prec[1]];
|
22
19
|
}
|
23
20
|
guess = nextGuess;
|
package/src/compare/max.js
CHANGED
@@ -2,7 +2,11 @@ import { bi2s, s2bi } from "../shared/utils.js";
|
|
2
2
|
import { maxInner } from "./utils.js";
|
3
3
|
/** This function returns max value. */
|
4
4
|
export const max = (array) => {
|
5
|
-
const arrayInner = array.
|
5
|
+
const arrayInner = Array(array.length);
|
6
|
+
for (let i = 0; i < array.length; i++) {
|
7
|
+
arrayInner[i] = s2bi(array[i]);
|
8
|
+
}
|
9
|
+
;
|
6
10
|
const bi = maxInner(arrayInner);
|
7
11
|
return bi2s(bi);
|
8
12
|
};
|
package/src/compare/min.js
CHANGED
@@ -2,7 +2,11 @@ import { bi2s, s2bi } from "../shared/utils.js";
|
|
2
2
|
import { minInner } from "./utils.js";
|
3
3
|
/** This function returns min value. */
|
4
4
|
export const min = (array) => {
|
5
|
-
const arrayInner = array.
|
5
|
+
const arrayInner = Array(array.length);
|
6
|
+
for (let i = 0; i < array.length; i++) {
|
7
|
+
arrayInner[i] = s2bi(array[i]);
|
8
|
+
}
|
9
|
+
;
|
6
10
|
const bi = minInner(arrayInner);
|
7
11
|
return bi2s(bi);
|
8
12
|
};
|
package/src/compare/utils.js
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import { tryBigInt } from "../shared/utils.js";
|
1
2
|
export const maxInner = (array) => {
|
2
3
|
let max = array[0];
|
3
4
|
for (let i = 1; i < array.length; i++) {
|
@@ -36,8 +37,8 @@ export const compareInner = (l, r) => {
|
|
36
37
|
if (fpeL === fpeR)
|
37
38
|
return [l, 0];
|
38
39
|
}
|
39
|
-
const fpeBiL =
|
40
|
-
const fpeBiR =
|
40
|
+
const fpeBiL = tryBigInt(fpeL);
|
41
|
+
const fpeBiR = tryBigInt(fpeR);
|
41
42
|
const max = fpeBiL > fpeBiR ? fpeBiL : fpeBiR;
|
42
43
|
const powL = biL * 10n ** (max - fpeBiL);
|
43
44
|
const powR = biR * 10n ** (max - fpeBiR);
|
@@ -55,8 +56,8 @@ export const compareInner = (l, r) => {
|
|
55
56
|
if (fpeL === fpeR)
|
56
57
|
return [l, 0];
|
57
58
|
}
|
58
|
-
const fpeBiL =
|
59
|
-
const fpeBiR =
|
59
|
+
const fpeBiL = tryBigInt(fpeL);
|
60
|
+
const fpeBiR = tryBigInt(fpeR);
|
60
61
|
const max = fpeBiL > fpeBiR ? fpeBiL : fpeBiR;
|
61
62
|
const powL = biL * 10n ** (max - fpeBiL);
|
62
63
|
const powR = biR * 10n ** (max - fpeBiR);
|
package/src/mean/mean.js
CHANGED
@@ -2,7 +2,10 @@ import { bi2s, s2bi } from "../shared/utils.js";
|
|
2
2
|
import { meanInner } from "./utils.js";
|
3
3
|
/** This function returns mean of an array. */
|
4
4
|
export const mean = (array) => {
|
5
|
-
const arrayInner = array.
|
5
|
+
const arrayInner = Array(array.length);
|
6
|
+
for (let i = 0; i < array.length; i++) {
|
7
|
+
arrayInner[i] = s2bi(array[i]);
|
8
|
+
}
|
6
9
|
const bi = meanInner(arrayInner);
|
7
10
|
return bi2s(bi);
|
8
11
|
};
|
package/src/mean/utils.js
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
import { PipeInner } from "../pipe/utils.js";
|
2
|
+
import { tryBigInt } from "../shared/utils.js";
|
2
3
|
export const meanInner = (array) => {
|
3
|
-
|
4
|
-
|
5
|
-
|
4
|
+
return new PipeInner().div([
|
5
|
+
new PipeInner().add(array).bi,
|
6
|
+
[tryBigInt(array.length), 0]
|
7
|
+
]).bi;
|
6
8
|
};
|
@@ -1,6 +1,6 @@
|
|
1
|
-
import { bi2s, s2bi,
|
2
|
-
const MAX_SUM =
|
3
|
-
const MIN_SUM = -
|
1
|
+
import { bi2s, calcInner, s2bi, tryBigInt, tryNumber } from "../../shared/utils.js";
|
2
|
+
const MAX_SUM = 8e+15;
|
3
|
+
const MIN_SUM = 8e-15;
|
4
4
|
/** This function adds numbers (as string). */
|
5
5
|
export const add = (array) => {
|
6
6
|
const arrayInner = Array(array.length);
|
@@ -11,7 +11,7 @@ export const add = (array) => {
|
|
11
11
|
while (i < array.length) {
|
12
12
|
fpi = array[i].indexOf(".");
|
13
13
|
if (array[i].length <= 15 && fpi === -1) {
|
14
|
-
sum +=
|
14
|
+
sum += tryNumber(array[i]);
|
15
15
|
}
|
16
16
|
else {
|
17
17
|
arrayInner[j] = s2bi(array[i], fpi);
|
@@ -19,14 +19,14 @@ export const add = (array) => {
|
|
19
19
|
}
|
20
20
|
i += 1;
|
21
21
|
if (sum > MAX_SUM || sum < MIN_SUM) {
|
22
|
-
arrayInner[j] = [
|
22
|
+
arrayInner[j] = [tryBigInt(sum), 0];
|
23
23
|
sum = 0;
|
24
24
|
j += 1;
|
25
25
|
}
|
26
26
|
}
|
27
27
|
if (i !== j)
|
28
28
|
arrayInner.length = j + 1;
|
29
|
-
arrayInner[j] = [
|
29
|
+
arrayInner[j] = [tryBigInt(sum), 0];
|
30
30
|
const bi = calcInner(arrayInner, (a, b) => a + b);
|
31
31
|
return bi2s(bi);
|
32
32
|
};
|
@@ -1,2 +1,2 @@
|
|
1
1
|
/** This function should divide numbers (as string). */
|
2
|
-
export declare const div: (array: string[],
|
2
|
+
export declare const div: (array: string[], precision?: number) => string;
|
@@ -1,8 +1,11 @@
|
|
1
1
|
import { bi2s, s2bi } from "../../shared/utils.js";
|
2
2
|
import { divInner } from "./utils.js";
|
3
3
|
/** This function should divide numbers (as string). */
|
4
|
-
export const div = (array,
|
5
|
-
const arrayInner = array.
|
6
|
-
|
4
|
+
export const div = (array, precision = 20) => {
|
5
|
+
const arrayInner = Array(array.length);
|
6
|
+
for (let i = 0; i < array.length; i++) {
|
7
|
+
arrayInner[i] = s2bi(array[i]);
|
8
|
+
}
|
9
|
+
const bi = divInner(arrayInner, precision !== null && precision !== void 0 ? precision : 20);
|
7
10
|
return bi2s(bi);
|
8
11
|
};
|
@@ -1,2 +1,2 @@
|
|
1
1
|
import type { BI } from "../../shared/types.d.ts";
|
2
|
-
export type DivInner = (array: BI[],
|
2
|
+
export type DivInner = (array: BI[], precision: number, def?: BI) => BI;
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
import { tryBigInt } from "../../shared/utils.js";
|
2
|
+
export const divInner = (array, precision, def) => {
|
2
3
|
let bigInt = def ? def[0] : array[0][0];
|
3
4
|
let fpe = def ? def[1] : array[0][1];
|
4
5
|
const isNeg = bigInt < 0n;
|
@@ -12,13 +13,13 @@ export const divInner = (array, limit, def) => {
|
|
12
13
|
dpLen = 0;
|
13
14
|
}
|
14
15
|
if (dpLen > 0 && fpe < dpLen) {
|
15
|
-
bigInt *= 10n **
|
16
|
+
bigInt *= 10n ** tryBigInt(dpLen - fpe);
|
16
17
|
fpe = 0;
|
17
18
|
}
|
18
19
|
if (dpLen > 0 && fpe > dpLen)
|
19
20
|
fpe = fpe - dpLen;
|
20
21
|
while ((bigInt < 0 ? bigInt * -1n : bigInt) < bigCurrent) {
|
21
|
-
if (
|
22
|
+
if (precision <= fpe)
|
22
23
|
return [bigInt / bigCurrent, fpe];
|
23
24
|
fpe += 1;
|
24
25
|
bigInt *= 10n;
|
@@ -26,7 +27,7 @@ export const divInner = (array, limit, def) => {
|
|
26
27
|
const q = bigInt / bigCurrent;
|
27
28
|
r = bigInt - q * bigCurrent;
|
28
29
|
bigInt = q;
|
29
|
-
while ((isNeg ? r < 0n : r > 0n) && fpe <
|
30
|
+
while ((isNeg ? r < 0n : r > 0n) && fpe < precision) {
|
30
31
|
const nextBigInt = r * 10n;
|
31
32
|
const nextQ = nextBigInt / bigCurrent;
|
32
33
|
const nextRemained = nextBigInt - nextQ * bigCurrent;
|
@@ -1,7 +1,10 @@
|
|
1
1
|
import { bi2s, calcInner, s2bi } from "../../shared/utils.js";
|
2
2
|
/** This function multiplies numbers (as string). */
|
3
3
|
export const mul = (array) => {
|
4
|
-
const arrayInner = array.
|
4
|
+
const arrayInner = Array(array.length);
|
5
|
+
for (let i = 0; i < array.length; i++) {
|
6
|
+
arrayInner[i] = s2bi(array[i]);
|
7
|
+
}
|
5
8
|
const bi = calcInner(arrayInner, (a, b) => a * b);
|
6
9
|
return bi2s(bi);
|
7
10
|
};
|
@@ -2,7 +2,10 @@ import { bi2s, s2bi } from "../../shared/utils.js";
|
|
2
2
|
import { calcInner } from "../../shared/utils.js";
|
3
3
|
/** This function subtracts numbers (as string). */
|
4
4
|
export function sub(array) {
|
5
|
-
const arrayInner = array.
|
5
|
+
const arrayInner = Array(array.length);
|
6
|
+
for (let i = 0; i < array.length; i++) {
|
7
|
+
arrayInner[i] = s2bi(array[i]);
|
8
|
+
}
|
6
9
|
const bi = calcInner(arrayInner, (a, b) => a - b);
|
7
10
|
return bi2s(bi);
|
8
11
|
}
|
package/src/pipe/pipe.d.ts
CHANGED
@@ -5,7 +5,7 @@ export declare class Pipe {
|
|
5
5
|
constructor(value?: string);
|
6
6
|
add(array: string[]): Pipe;
|
7
7
|
sub(array: string[]): Pipe;
|
8
|
-
div(array: string[],
|
8
|
+
div(array: string[], precision?: number): Pipe;
|
9
9
|
mul(array: string[]): Pipe;
|
10
10
|
abs(): Pipe;
|
11
11
|
calc(): ReturnType<BI2S>;
|
package/src/pipe/pipe.js
CHANGED
@@ -29,9 +29,9 @@ export class Pipe {
|
|
29
29
|
__classPrivateFieldSet(this, _Pipe_result, calcInner(arrayInner, (a, b) => a - b, __classPrivateFieldGet(this, _Pipe_result, "f")), "f");
|
30
30
|
return this;
|
31
31
|
}
|
32
|
-
div(array,
|
32
|
+
div(array, precision = 20) {
|
33
33
|
const arrayInner = array.map((str) => s2bi(str));
|
34
|
-
__classPrivateFieldSet(this, _Pipe_result, divInner(arrayInner,
|
34
|
+
__classPrivateFieldSet(this, _Pipe_result, divInner(arrayInner, precision, __classPrivateFieldGet(this, _Pipe_result, "f")), "f");
|
35
35
|
return this;
|
36
36
|
}
|
37
37
|
mul(array) {
|
package/src/pipe/utils.d.ts
CHANGED
@@ -4,7 +4,8 @@ export declare class PipeInner {
|
|
4
4
|
constructor();
|
5
5
|
add(array: BI[]): PipeInner;
|
6
6
|
sub(array: BI[]): PipeInner;
|
7
|
-
div(array: BI[],
|
7
|
+
div(array: BI[], precision?: number): PipeInner;
|
8
8
|
mul(array: BI[]): PipeInner;
|
9
|
-
|
9
|
+
abs(): PipeInner;
|
10
|
+
get bi(): BI;
|
10
11
|
}
|
package/src/pipe/utils.js
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import { calcInner } from "../shared/utils.js";
|
2
2
|
import { divInner } from "../operations/div/utils.js";
|
3
|
+
import { absInner } from "../abs/utils.js";
|
3
4
|
export class PipeInner {
|
4
5
|
constructor() { }
|
5
6
|
add(array) {
|
@@ -10,17 +11,20 @@ export class PipeInner {
|
|
10
11
|
this.result = calcInner(array, (a, b) => a - b, this.result);
|
11
12
|
return this;
|
12
13
|
}
|
13
|
-
div(array,
|
14
|
-
this.result = divInner(array,
|
14
|
+
div(array, precision = 20) {
|
15
|
+
this.result = divInner(array, precision, this.result);
|
15
16
|
return this;
|
16
17
|
}
|
17
18
|
mul(array) {
|
18
19
|
this.result = calcInner(array, (a, b) => a * b, this.result);
|
19
20
|
return this;
|
20
21
|
}
|
21
|
-
|
22
|
+
abs() {
|
23
|
+
this.result && (this.result = absInner(this.result));
|
24
|
+
return this;
|
25
|
+
}
|
26
|
+
get bi() {
|
22
27
|
var _a;
|
23
|
-
|
24
|
-
return res;
|
28
|
+
return (_a = this.result) !== null && _a !== void 0 ? _a : [0n, 0];
|
25
29
|
}
|
26
30
|
}
|
package/src/quartile/quartile.js
CHANGED
@@ -2,7 +2,10 @@ import { bi2s, s2bi } from "../shared/utils.js";
|
|
2
2
|
import { quartileInner } from "./utils.js";
|
3
3
|
/** This function returns Q1, Q2, Q3 (quartile). */
|
4
4
|
export const quartile = (array) => {
|
5
|
-
const arrayInner = array.
|
5
|
+
const arrayInner = Array(array.length);
|
6
|
+
for (let i = 0; i < array.length; i++) {
|
7
|
+
arrayInner[i] = s2bi(array[i]);
|
8
|
+
}
|
6
9
|
const { Q1, Q2, Q3 } = quartileInner(arrayInner);
|
7
10
|
return {
|
8
11
|
Q1: bi2s(Q1),
|
package/src/quartile/utils.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import { PipeInner } from "../pipe/utils.js";
|
2
2
|
const meanQ = (idx, array) => {
|
3
|
-
const left = new PipeInner().add([array[idx], array[idx - 1]])
|
4
|
-
return new PipeInner().div([left, [2n, 0]]).
|
3
|
+
const { bi: left } = new PipeInner().add([array[idx], array[idx - 1]]);
|
4
|
+
return new PipeInner().div([left, [2n, 0]]).bi;
|
5
5
|
};
|
6
6
|
export const quartileInner = (array) => {
|
7
7
|
if (array.length < 3) {
|
package/src/shared/types.d.ts
CHANGED
@@ -4,4 +4,3 @@ export type TrimTail = (str: string) => string;
|
|
4
4
|
export type CalcInner = (array: BI[], op: (a: bigint, b: bigint) => bigint, def?: BI) => BI;
|
5
5
|
export type BI2S = (value: BI) => string;
|
6
6
|
export type S2BI = (str: string, fpi?: number) => BI;
|
7
|
-
export type GetBigInt = (value: string, type: "di" | "hbo" | "si" | "reg", fpi: number) => bigint;
|
package/src/shared/utils.d.ts
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
import type { BI2S, CalcInner, FillHead,
|
1
|
+
import type { BI2S, CalcInner, FillHead, S2BI, TrimTail } from "./types.d.ts";
|
2
2
|
export declare const bi2s: BI2S;
|
3
3
|
export declare const s2bi: S2BI;
|
4
|
-
export declare const getBigInt: GetBigInt;
|
5
4
|
export declare const calcInner: CalcInner;
|
6
5
|
export declare const fillHead: FillHead;
|
7
6
|
export declare const trimTail: TrimTail;
|
7
|
+
export declare const tryBigInt: <T extends number | string>(value: T) => bigint;
|
8
|
+
export declare const tryNumber: (value: string, origin?: string) => number;
|
package/src/shared/utils.js
CHANGED
@@ -3,7 +3,7 @@ export const bi2s = ([bigInt, fpe]) => {
|
|
3
3
|
return "0";
|
4
4
|
const isNeg = bigInt < 0n;
|
5
5
|
isNeg && (bigInt *= -1n);
|
6
|
-
const dp = bigInt % (10n **
|
6
|
+
const dp = bigInt % (10n ** tryBigInt(fpe));
|
7
7
|
const bigStr = bigInt.toString();
|
8
8
|
let fpIdx = bigStr.length - fpe;
|
9
9
|
if (fpIdx < 0)
|
@@ -24,41 +24,24 @@ export const s2bi = (str, _fpi) => {
|
|
24
24
|
str.startsWith("-0O") || str.startsWith("0O");
|
25
25
|
const isBinary = str.startsWith("0b") || str.startsWith("-0b") ||
|
26
26
|
str.startsWith("-0B") || str.startsWith("0B");
|
27
|
-
if (fpi === -1 && !isHex && !isOctal && !isBinary)
|
28
|
-
return [
|
29
|
-
}
|
27
|
+
if (fpi === -1 && !isHex && !isOctal && !isBinary)
|
28
|
+
return [tryBigInt(str), 0];
|
30
29
|
if (isHex || isBinary || isOctal) {
|
31
30
|
const isNegative = str[0] === "-";
|
32
|
-
const bi =
|
31
|
+
const bi = tryBigInt(str.slice(isNegative ? 1 : 0));
|
33
32
|
return [isNegative ? -1n * bi : bi, 0];
|
34
33
|
}
|
35
34
|
if (str.length < 15 && str[0] !== "0") {
|
36
35
|
return [
|
37
|
-
|
36
|
+
tryBigInt(tryNumber(str.slice(0, fpi) + str.slice(fpi + 1), str)),
|
38
37
|
str.length - 1 - fpi,
|
39
38
|
];
|
40
39
|
}
|
41
40
|
return [
|
42
|
-
|
41
|
+
tryBigInt(str.slice(0, fpi) + str.slice(fpi + 1)),
|
43
42
|
str.length - 1 - fpi,
|
44
43
|
];
|
45
44
|
};
|
46
|
-
export const getBigInt = (value, type, fpi) => {
|
47
|
-
let bi = 0n;
|
48
|
-
const typeMap = {
|
49
|
-
di: value,
|
50
|
-
hbo: value.slice(value[0] === "-" ? 1 : 0),
|
51
|
-
si: +(value.slice(0, fpi) + value.slice(fpi + 1)),
|
52
|
-
reg: value.slice(0, fpi) + value.slice(fpi + 1),
|
53
|
-
};
|
54
|
-
try {
|
55
|
-
bi = BigInt(typeMap[type]);
|
56
|
-
}
|
57
|
-
catch (_) {
|
58
|
-
throw new Error(`${value} is not valid input`);
|
59
|
-
}
|
60
|
-
return bi;
|
61
|
-
};
|
62
45
|
export const calcInner = (array, op, def) => {
|
63
46
|
let totalBi = def ? def[0] : array[0][0];
|
64
47
|
let totalFpe = def ? def[1] : array[0][1];
|
@@ -76,10 +59,10 @@ export const calcInner = (array, op, def) => {
|
|
76
59
|
else {
|
77
60
|
if (totalFpe < fpe) {
|
78
61
|
const fpDiff = fpe - totalFpe;
|
79
|
-
totalBi = op(totalBi * (10n **
|
62
|
+
totalBi = op(totalBi * (10n ** tryBigInt(fpDiff)), bi);
|
80
63
|
}
|
81
64
|
if (totalFpe > fpe) {
|
82
|
-
totalBi = op(totalBi, bi * (10n **
|
65
|
+
totalBi = op(totalBi, bi * (10n ** tryBigInt(totalFpe - fpe)));
|
83
66
|
}
|
84
67
|
if (totalFpe === fpe)
|
85
68
|
totalBi = op(totalBi, bi);
|
@@ -108,3 +91,19 @@ export const trimTail = (str) => {
|
|
108
91
|
}
|
109
92
|
return str;
|
110
93
|
};
|
94
|
+
export const tryBigInt = (value) => {
|
95
|
+
let bi;
|
96
|
+
try {
|
97
|
+
bi = BigInt(value);
|
98
|
+
}
|
99
|
+
catch (_) {
|
100
|
+
throw new Error(`Invalid input: ${value}`);
|
101
|
+
}
|
102
|
+
return bi;
|
103
|
+
};
|
104
|
+
export const tryNumber = (value, origin = value) => {
|
105
|
+
const num = +value;
|
106
|
+
if (Number.isNaN(num))
|
107
|
+
throw new Error(`Invalid input: ${origin}`);
|
108
|
+
return num;
|
109
|
+
};
|
package/src/sort/sort.js
CHANGED
@@ -3,7 +3,10 @@ import { ASC } from "./constants.js";
|
|
3
3
|
import { sortInner } from "./utils.js";
|
4
4
|
/** Using this function sort an array. */
|
5
5
|
export const sort = (array, sorting = ASC) => {
|
6
|
-
const arrayInner = array.
|
6
|
+
const arrayInner = Array(array.length);
|
7
|
+
for (let i = 0; i < array.length; i++) {
|
8
|
+
arrayInner[i] = s2bi(array[i]);
|
9
|
+
}
|
7
10
|
sortInner(arrayInner, sorting);
|
8
11
|
return arrayInner.map((bi) => bi2s(bi));
|
9
12
|
};
|
package/src/sqrt/utils.js
CHANGED
@@ -1,20 +1,17 @@
|
|
1
1
|
import { isLeftGreaterInner } from "../compare/utils.js";
|
2
2
|
import { PipeInner } from "../pipe/utils.js";
|
3
3
|
export const sqrtInner = (value, prec = [1n, 13], max = 100) => {
|
4
|
-
var _a;
|
5
4
|
if (value[0] < 0n) {
|
6
5
|
throw new Error("Invalid input: Cannot take the square root of a negative value.");
|
7
6
|
}
|
8
7
|
let guess = value;
|
9
8
|
for (let i = 0; i < max; i++) {
|
10
|
-
const nextGuess
|
9
|
+
const { bi: nextGuess } = new PipeInner()
|
11
10
|
.div([value, guess])
|
12
11
|
.add([guess])
|
13
|
-
.mul([[5n, 1]])
|
14
|
-
|
15
|
-
if (bi
|
16
|
-
bi *= -1n;
|
17
|
-
if (isLeftGreaterInner({ left: prec, right: [bi, fpe] })) {
|
12
|
+
.mul([[5n, 1]]);
|
13
|
+
const { bi } = new PipeInner().sub([nextGuess, guess]).abs();
|
14
|
+
if (isLeftGreaterInner({ left: prec, right: bi })) {
|
18
15
|
return [nextGuess, prec[1]];
|
19
16
|
}
|
20
17
|
guess = nextGuess;
|