@numio/bigmath 2.2.7 → 2.3.0

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 CHANGED
@@ -1,3 +1,8 @@
1
+ ### 2.2.8
2
+ Better error handling
3
+ Add FDR - Freedman-Diaconis Rule
4
+ MAD - median of the absolute deviations from `median` or `mean`
5
+
1
6
  ### 2.2.7
2
7
  Throw an error if input is not valid. In the error show exact invalid input.
3
8
 
package/README.md CHANGED
@@ -1,68 +1,54 @@
1
1
  # @numio/bigmath: Precise Arithmetic Beyond JavaScript's Limits
2
2
 
3
- **Do you struggle with inaccurate calculations involving very large or very small numbers, or decimal numbers with high precision in JavaScript?**
4
-
5
- `@numio/bigmath` is your solution! This library provides a robust set of functions for performing **arbitrary-precision arithmetic**, effectively overcoming the limitations of JavaScript's built-in `Number` type. Say goodbye to unexpected rounding errors and precision loss when dealing with numbers that exceed 15 significant digits or involve complex decimal operations.
6
-
7
- ## Why Choose @numio/bigmath?
8
-
9
- **Solve Precision Problems:**
10
-
11
- * **Handle Numbers of Any Size:** Perform calculations on integers and decimals of virtually unlimited length, without the risk of JavaScript's `Number` limitations.
12
- * **Eliminate Precision Loss:** Achieve accurate results even with numeric literals exceeding 15 significant digits, ensuring the integrity of your calculations.
13
- * **Precise Decimal Operations:** Execute addition, subtraction, multiplication, and division on decimal numbers with guaranteed accuracy, including scenarios with negative values.
14
- * ****NEW! Multi-Base Number Support:** Seamlessly perform arithmetic operations involving **hexadecimal (HEX), octal, binary, and decimal numbers**, offering unparalleled flexibility in handling various number formats.
15
- * ****NEW! Number Format Validation:** Easily validate if a string represents a valid **hexadecimal (`isHex`)**, **binary (`isBinary`)**, **decimal (`isDecimal`)**, **octal (`isOctal`)**, or any valid **number (`isNumber`)** format supported by the library.
16
-
17
-
18
-
19
- **Unlock Advanced Numerical Operations:**
20
-
21
- * **Control Division Precision:** Specify the exact number of digits after the decimal point for division results, with a default precision of 20 digits for high accuracy.
22
- * **Flexible Rounding:** Round numbers to the nearest integer or a specific number of decimal places with various rounding modes (up, down, half-up, half-down, half-even, half-odd) to meet your exact requirements.
23
- * **Round Based on Significant Figures:** Control rounding based on the number of significant figures, crucial for scientific and engineering applications.
24
- * **Calculate Roots:**
25
- * **Calculate Square Root (`sqrt`):** Compute the square root of a number with arbitrary precision. You can also specify the desired precision of the result.
26
- * ****NEW! Calculate Cube Root (`cbrt`):** Determine the cube root of a number with arbitrary precision, allowing you to specify the desired accuracy.
27
-
28
- * **Chain Operations with Pipe:** Simplify complex calculations by chaining arithmetic operations in a readable and intuitive manner.
29
- * **Analyze Data Distribution:**
30
- * **Calculate Quartiles (Q1, Q2, Q3):** Understand the spread and central tendency of your numerical data, helping identify outliers and the shape of the distribution.
31
- * **Calculate Median Absolute Deviation (MAD):** Measure the dispersion of a dataset, providing a robust alternative to standard deviation that is less sensitive to outliers.
32
- * **Calculate Interquartile Range (IQR):** Determine the spread of the middle 50% of your data, useful for identifying the central bulk and potential outliers.
33
- * **Compare Numbers:**
34
- * **Check for Equality (`isEqual`):** Accurately determine if two arbitrary-precision numbers are equal.
35
- * **Check if Left is Greater (`isLeftGreater`):** Precisely compare two arbitrary-precision numbers to see if the left operand is greater than the right.
36
- * ****NEW! Check if Left is Greater or Equal (`isLeftGreaterOrEqual`):** Precisely compare two arbitrary-precision numbers to determine if the left operand is greater than or equal to the right.
37
- * **Sort Numbers Accurately:** Sort arrays of numbers, including negative and decimal values, in ascending or descending order, correctly handling string representations of numbers that JavaScript's native sort might misinterpret.
38
- * **Calculate Central Tendency:** Easily compute the mean (average) of a set of numbers.
39
- * **Identify Extremes:** Find the maximum and minimum values within an array of numbers.
40
- * ****NEW! Calculate Absolute Value (`abs`):** Determine the non-negative value of a number, regardless of its sign.
41
- * ****NEW! Convert Number to Another Base (`toBase`):** Seamlessly convert numbers between decimal, hexadecimal (HEX), binary, and octal representations.
42
-
43
- ## When is @numio/bigmath essential?
44
-
45
- This library is particularly invaluable in applications where numerical accuracy and the ability to handle large numbers are paramount:
46
-
47
- * **Financial Applications:** Accurate calculations for large sums of money, precise interest rates, and complex financial modeling.
48
- * **Scientific Computing:** Working with extremely large or small numbers in simulations, data analysis, and research.
49
- * **Cryptography:** Implementing cryptographic algorithms that rely on high-precision arithmetic.
50
- * **E-commerce and Payments:** Handling precise amounts and avoiding rounding errors in transactions.
51
- * **Data Analysis and Statistics:** Performing accurate statistical calculations on datasets with varying scales.
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/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.2.7",
4
+ "version": "2.3.0",
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",
@@ -0,0 +1,2 @@
1
+ import type { TFDR } from "./types.d.ts";
2
+ export declare const FDR: TFDR;
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 {};
@@ -0,0 +1,2 @@
1
+ import type { FDRInner } from "./types.d.ts";
2
+ export declare const fdrInner: FDRInner;
@@ -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, sigNum) => {
5
- const arrayInner = array.map((str) => s2bi(str));
6
- const bi = IQRInner(arrayInner, sigNum);
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
  };
@@ -1,3 +1,3 @@
1
1
  import type { BI } from "../shared/types.d.ts";
2
- export type TIQR = (array: string[], sigNum?: boolean) => string;
3
- export type TIQRInner = (array: BI[], sigNum?: boolean) => BI;
2
+ export type TIQR = (array: string[]) => string;
3
+ export type TIQRInner = (array: BI[]) => BI;
@@ -1,3 +1,2 @@
1
1
  import type { TIQRInner } from "./types.d.ts";
2
- export declare const MIN_LENGTH_FOR_MAD = 30;
3
2
  export declare const IQRInner: TIQRInner;
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 MIN_LENGTH_FOR_MAD = 30;
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]).calc();
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.map((str) => s2bi(str));
6
- const bi = MADInner(arrayInner);
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
  };
@@ -1,3 +1,8 @@
1
1
  import type { BI } from "../shared/types.d.ts";
2
- export type TMAD = (array: string[]) => string;
3
- export type TMADInner = (array: BI[]) => BI;
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 median = quartileInner(array).Q2;
10
+ const fromMap = {
11
+ median: quartileInner(array).Q2,
12
+ mean: meanInner(array)
13
+ };
10
14
  const madArray = array.map((el) => {
11
- const [bi, fpe] = new PipeInner().sub([el, median]).calc();
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 = (_a = new PipeInner().add([
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]]).result) !== null && _a !== void 0 ? _a : [0n, 0];
17
- let [bi, fpe] = (_b = new PipeInner().sub([nextGuess, guess]).result) !== null && _b !== void 0 ? _b : [0n, 0];
18
- if (bi < 0n)
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;
@@ -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.map((str) => s2bi(str));
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
  };
@@ -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.map((str) => s2bi(str));
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
  };
@@ -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 = BigInt(fpeL);
40
- const fpeBiR = BigInt(fpeR);
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 = BigInt(fpeL);
59
- const fpeBiR = BigInt(fpeR);
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.map((str) => s2bi(str));
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
- const left = new PipeInner().add(array).calc();
4
- const right = [BigInt(array.length), 0];
5
- return new PipeInner().div([left, right]).calc();
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, calcInner } from "../../shared/utils.js";
2
- const MAX_SUM = 8000000000000000;
3
- const MIN_SUM = -8000000000000000;
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 += +array[i];
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] = [BigInt(sum), 0];
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] = [BigInt(sum), 0];
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[], limit?: number) => 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, limit = 20) => {
5
- const arrayInner = array.map((str) => s2bi(str));
6
- const bi = divInner(arrayInner, limit !== null && limit !== void 0 ? limit : 20);
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[], limit: number, def?: BI) => BI;
2
+ export type DivInner = (array: BI[], precision: number, def?: BI) => BI;
@@ -1,4 +1,5 @@
1
- export const divInner = (array, limit, def) => {
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 ** BigInt(dpLen - fpe);
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 (limit <= fpe)
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 < limit) {
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.map((str) => s2bi(str));
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.map((str) => s2bi(str));
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
  }
@@ -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[], limit?: number): Pipe;
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, limit = 20) {
32
+ div(array, precision = 20) {
33
33
  const arrayInner = array.map((str) => s2bi(str));
34
- __classPrivateFieldSet(this, _Pipe_result, divInner(arrayInner, limit, __classPrivateFieldGet(this, _Pipe_result, "f")), "f");
34
+ __classPrivateFieldSet(this, _Pipe_result, divInner(arrayInner, precision, __classPrivateFieldGet(this, _Pipe_result, "f")), "f");
35
35
  return this;
36
36
  }
37
37
  mul(array) {
@@ -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[], limit?: number): PipeInner;
7
+ div(array: BI[], precision?: number): PipeInner;
8
8
  mul(array: BI[]): PipeInner;
9
- calc(): BI;
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, limit = 20) {
14
- this.result = divInner(array, limit, this.result);
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
- calc() {
22
+ abs() {
23
+ this.result && (this.result = absInner(this.result));
24
+ return this;
25
+ }
26
+ get bi() {
22
27
  var _a;
23
- const res = (_a = this.result) !== null && _a !== void 0 ? _a : [0n, 0];
24
- return res;
28
+ return (_a = this.result) !== null && _a !== void 0 ? _a : [0n, 0];
25
29
  }
26
30
  }
@@ -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.map((str) => s2bi(str));
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),
@@ -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]]).calc();
4
- return new PipeInner().div([left, [2n, 0]]).calc();
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) {
@@ -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;
@@ -1,7 +1,8 @@
1
- import type { BI2S, CalcInner, FillHead, GetBigInt, S2BI, TrimTail } from "./types.d.ts";
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;
@@ -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 ** BigInt(fpe));
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 [getBigInt(str, "di", fpi), 0];
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 = getBigInt(str, "hbo", fpi);
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
- getBigInt(str, "si", fpi),
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
- getBigInt(str, "reg", fpi),
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 ** BigInt(fpDiff)), bi);
62
+ totalBi = op(totalBi * (10n ** tryBigInt(fpDiff)), bi);
80
63
  }
81
64
  if (totalFpe > fpe) {
82
- totalBi = op(totalBi, bi * (10n ** BigInt(totalFpe - fpe)));
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.map((str) => s2bi(str));
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 = (_a = new PipeInner()
9
+ const { bi: nextGuess } = new PipeInner()
11
10
  .div([value, guess])
12
11
  .add([guess])
13
- .mul([[5n, 1]]).result) !== null && _a !== void 0 ? _a : [0n, 0];
14
- let [bi, fpe] = new PipeInner().sub([nextGuess, guess]).calc();
15
- if (bi < 0n)
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;