@numio/bigmath 2.0.1 → 2.1.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/README.md CHANGED
@@ -21,6 +21,8 @@
21
21
  * **Round Based on Significant Figures:** Control rounding based on the number of significant figures, crucial for scientific and engineering applications.
22
22
  * **Calculate Roots:**
23
23
  * **Calculate Square Root (`sqrt`):** Compute the square root of a number with arbitrary precision. You can also specify the desired precision of the result.
24
+ * **NEW! Calculate Cube Root (`cbrt`):** Determine the cube root of a number with arbitrary precision, allowing you to specify the desired accuracy.
25
+
24
26
  * **Chain Operations with Pipe:** Simplify complex calculations by chaining arithmetic operations in a readable and intuitive manner.
25
27
  * **Analyze Data Distribution:**
26
28
  * **Calculate Quartiles (Q1, Q2, Q3):** Understand the spread and central tendency of your numerical data, helping identify outliers and the shape of the distribution.
@@ -29,9 +31,12 @@
29
31
  * **Compare Numbers:**
30
32
  * **Check for Equality (`isEqual`):** Accurately determine if two arbitrary-precision numbers are equal.
31
33
  * **Check if Left is Greater (`isLeftGreater`):** Precisely compare two arbitrary-precision numbers to see if the left operand is greater than the right.
34
+ * **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.
32
35
  * **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.
33
36
  * **Calculate Central Tendency:** Easily compute the mean (average) of a set of numbers.
34
37
  * **Identify Extremes:** Find the maximum and minimum values within an array of numbers.
38
+ * **NEW! Calculate Absolute Value (`abs`):** Determine the non-negative value of a number, regardless of its sign.
39
+ * **NEW! Convert Number to Another Base (`toBase`):** Seamlessly convert numbers between decimal, hexadecimal (HEX), binary, and octal representations.
35
40
 
36
41
  ## When is @numio/bigmath essential?
37
42
 
@@ -208,18 +213,24 @@ round("1.000119", { decimals: 2, sigFig: true }); // 1
208
213
  ### Pipe
209
214
 
210
215
  ```javascript
211
- import { pipe } from "@numio/bigmath";
216
+ import { Pipe } from "@numio/bigmath";
212
217
 
213
218
  const addNums = ["1", "2", "3"];
214
219
  const subNums = ["0.2", "0.3"];
215
220
  const divNums = ["4"];
216
221
  const mulNums = ["2", "5", "0.2"];
217
222
 
218
- pipe.add(addNums) // 6
223
+ new Pipe().add(addNums) // 6
219
224
  .div(divNums) // 6 / 4 = 1.5
220
225
  .sub(subNums) // 1.5 - 0.2 - 0.3 = 1
221
226
  .mul(mulNums) // 1 * 2 * 5 * 0.2 = 2
222
227
  .calc() // convert end result to readable string
228
+
229
+ new Pipe().sub(["1", "5"]) // 1 - 5 = -4
230
+ .abs() // 4 - returns absolute value
231
+
232
+ new Pipe().add(["10", "5"]) // 11 + 5 = 15
233
+ .resultToBase(16) // f - returns result converted to base 16
223
234
  ```
224
235
 
225
236
  ### Quartile
@@ -289,6 +300,16 @@ isLeftGreater({left: "0.1", right: "0.1"}) // false;
289
300
  isLeftGreater({left: "0.1", right: "-0.1"}) // true;
290
301
  ```
291
302
 
303
+ ### IsLeftGreaterOrEqual
304
+ ```javascript
305
+ import { isLeftGreaterOrEqual } from "@numio/bigmath";
306
+
307
+ isLeftGreaterOrEqual({left: "0.1", right: "2"}) // false;
308
+ isLeftGreaterOrEqual({left: "2", right: "0.1"}) // true;
309
+ isLeftGreaterOrEqual({left: "0.1", right: "0.1"}) // true;
310
+ isLeftGreaterOrEqual({left: "0.1", right: "-0.1"}) // true;
311
+ ```
312
+
292
313
  ### MAD - Median Absolute Deviation
293
314
  ```javascript
294
315
  import { MAD } from "@numio/bigmath";
@@ -315,12 +336,46 @@ sqrt("3", "0.01") // 1.732;
315
336
  sqrt("3", "0.000000000000000000001") // 1.732050807568877293527;
316
337
  ```
317
338
 
339
+ ### CBRT - cube root of a number
340
+ ```javascript
341
+ import { cbrt } from "@numio/bigmath";
342
+
343
+ cbrt("37") // 3;
344
+ cbrt("1000") // 10;
345
+ cbrt("15"), // 2.4662120743305
346
+
347
+ // you can change precision of a result (second parameter),
348
+ cbrt("15", "0.001") // 2.466
349
+ ```
350
+
351
+ ### ABS - absolute value
352
+ ```javascript
353
+ import { abs } from "@numio/bigmath";
354
+
355
+ abs("-1") // 1;
356
+ abs("1") // 1;
357
+ ```
358
+
359
+ ### toBase - convert number to another base
360
+ ```javascript
361
+ import { toBase } from "@numio/bigmath";
362
+
363
+ toBase({ value: "11", toBase: 16 }) // b
364
+ // 0x - HEX
365
+ toBase({ value: "0xb", toBase: 10 }) // 11
366
+ // 0b - binary
367
+ toBase({ value: "0b101", toBase: 10 }) // 5
368
+ toBase({ value: "0b1101", toBase: 16 }) // d
369
+ // 0o - octal
370
+ toBase({ value: "0o11", toBase: 10 }) // 9
371
+ ```
372
+
318
373
  Does not have a limitation on the number of digits. You can use any length you'd
319
374
  like
320
375
 
321
376
  ```javascript
322
377
  // NO precision loss using numeric literals with more than 15 significant digits.
323
- const int = sub(
378
+ const int = add(
324
379
  "999999999999999999999999999999999999999999999999999999999999999",
325
380
  "2",
326
381
  ); // "1000000000000000000000000000000000000000000000000000000000000001"
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.0.1",
4
+ "version": "2.1.0",
5
5
  "keywords": [
6
6
  "precision",
7
7
  "arithmetic",
@@ -0,0 +1,2 @@
1
+ import type { Abs } from "./types.d.ts";
2
+ export declare const abs: Abs;
@@ -0,0 +1,6 @@
1
+ import { bi2s, s2bi } from "../shared/utils.js";
2
+ import { absInner } from "./utils.js";
3
+ export const abs = (value) => {
4
+ const [bi, fpe] = absInner(s2bi(value));
5
+ return bi2s(bi, fpe);
6
+ };
@@ -0,0 +1,3 @@
1
+ import type { BI } from "../shared/types.d.ts";
2
+ export type Abs = (value: string) => string;
3
+ export type AbsInner = (value: BI) => BI;
@@ -0,0 +1,2 @@
1
+ import type { AbsInner } from "./types.d.ts";
2
+ export declare const absInner: AbsInner;
@@ -0,0 +1,3 @@
1
+ export const absInner = ([bi, fpe]) => {
2
+ return [bi < 0n ? bi * -1n : bi, fpe];
3
+ };
@@ -0,0 +1,3 @@
1
+ import type { Cbrt } from "./types.d.ts";
2
+ /** Find cube root of a number */
3
+ export declare const cbrt: Cbrt;
@@ -0,0 +1,9 @@
1
+ import { round } from "../round/main.js";
2
+ import { bi2s, s2bi } from "../shared/utils.js";
3
+ import { cbrtInner } from "./utils.js";
4
+ /** Find cube root of a number */
5
+ export const cbrt = (value, precision) => {
6
+ const valueInner = s2bi(value);
7
+ const [[bi, fpe], decimals] = cbrtInner(valueInner, precision ? s2bi(precision) : undefined);
8
+ return round(bi2s(bi, fpe), { decimals });
9
+ };
@@ -0,0 +1,3 @@
1
+ import type { BI } from "../shared/types.d.ts";
2
+ export type CbrtInner = (value: BI, prec?: BI, max?: number) => [BI, number];
3
+ export type Cbrt = (value: string, precision?: string) => string;
@@ -0,0 +1,2 @@
1
+ import type { CbrtInner } from "./types.d.ts";
2
+ export declare const cbrtInner: CbrtInner;
@@ -0,0 +1,22 @@
1
+ import { isLeftGreaterInner } from "../compare/utils.js";
2
+ import { divInner } from "../operations/div/utils.js";
3
+ import { PipeInner } from "../pipe/utils.js";
4
+ import { calcInner } from "../shared/utils.js";
5
+ export const cbrtInner = (value, prec = [1n, 13], max = 100) => {
6
+ let guess = value;
7
+ for (let i = 0; i < max; i++) {
8
+ const mul = calcInner([guess, guess], (a, b) => a * b);
9
+ const nextGuess = new PipeInner().add([
10
+ calcInner([guess, [2n, 0]], (a, b) => a * b),
11
+ divInner([value, mul], 20),
12
+ ]).div([[3n, 0]]).calc();
13
+ let [bi, fpe] = new PipeInner().sub([nextGuess, guess]).calc();
14
+ if (bi < 0n)
15
+ bi *= -1n;
16
+ if (isLeftGreaterInner({ left: prec, right: [bi, fpe] })) {
17
+ return [nextGuess, prec[1]];
18
+ }
19
+ guess = nextGuess;
20
+ }
21
+ return [guess, prec[1]];
22
+ };
@@ -1,9 +1,11 @@
1
- import type { IsEqual, IsLeftGreater, Max, Min } from "./types.d.ts";
1
+ import type { IsEqual, IsLeftGreater, IsLeftGreaterOrEqual, Max, Min } from "./types.d.ts";
2
2
  /** This function returns max value. */
3
3
  export declare const max: Max;
4
4
  /** This function returns min value. */
5
5
  export declare const min: Min;
6
6
  /** This function returns if left value is greater than right value */
7
7
  export declare const isLeftGreater: IsLeftGreater;
8
+ /** This function returns if left value is greater than right value */
9
+ export declare const isLeftGreaterOrEqual: IsLeftGreaterOrEqual;
8
10
  /** This function returns if left and right values are equal */
9
11
  export declare const isEqual: IsEqual;
@@ -1,5 +1,5 @@
1
1
  import { bi2s, s2bi } from "../shared/utils.js";
2
- import { isEqualInner, isLeftGreaterInner, maxInner, minInner, } from "./utils.js";
2
+ import { isEqualInner, isLeftGreaterInner, isLeftGreaterOrEqualInner, maxInner, minInner, } from "./utils.js";
3
3
  /** This function returns max value. */
4
4
  export const max = (array) => {
5
5
  const arrayInner = array.map((str) => s2bi(str));
@@ -16,6 +16,10 @@ export const min = (array) => {
16
16
  export const isLeftGreater = ({ left, right }) => {
17
17
  return isLeftGreaterInner({ left: s2bi(left), right: s2bi(right) });
18
18
  };
19
+ /** This function returns if left value is greater than right value */
20
+ export const isLeftGreaterOrEqual = ({ left, right }) => {
21
+ return isLeftGreaterOrEqualInner({ left: s2bi(left), right: s2bi(right) });
22
+ };
19
23
  /** This function returns if left and right values are equal */
20
24
  export const isEqual = ({ left, right }) => {
21
25
  return isEqualInner({ left: s2bi(left), right: s2bi(right) });
@@ -1,16 +1,24 @@
1
1
  import type { BI } from "../shared/types.d.ts";
2
2
  export type Min = (strs: string[]) => string;
3
3
  export type Max = Min;
4
- export type IsLeftGreater = (attr: {
4
+ export type IsLeftGreater = (arg: {
5
+ left: string;
6
+ right: string;
7
+ }) => boolean;
8
+ export type IsEqual = (arg: {
9
+ left: string;
10
+ right: string;
11
+ }) => boolean;
12
+ export type IsLeftGreaterOrEqual = (arg: {
5
13
  left: string;
6
14
  right: string;
7
15
  }) => boolean;
8
- export type IsEqual = IsLeftGreater;
9
16
  export type CompareInner = (left: BI, right: BI) => [BI, number];
10
17
  export type MinInner = (array: BI[]) => BI;
11
18
  export type MaxInner = MinInner;
12
- export type IsEqualInner = (attr: {
19
+ export type IsEqualInner = (arg: {
13
20
  left: BI;
14
21
  right: BI;
15
22
  }) => boolean;
16
23
  export type IsLeftGreaterInner = IsEqualInner;
24
+ export type IsLeftGreaterOrEqualInner = IsEqualInner;
@@ -1,6 +1,7 @@
1
- import type { CompareInner, IsEqualInner, IsLeftGreaterInner, MaxInner, MinInner } from "./types.d.ts";
1
+ import type { CompareInner, IsEqualInner, IsLeftGreaterInner, IsLeftGreaterOrEqualInner, MaxInner, MinInner } from "./types.d.ts";
2
2
  export declare const maxInner: MaxInner;
3
3
  export declare const minInner: MinInner;
4
4
  export declare const compareInner: CompareInner;
5
5
  export declare const isEqualInner: IsEqualInner;
6
6
  export declare const isLeftGreaterInner: IsLeftGreaterInner;
7
+ export declare const isLeftGreaterOrEqualInner: IsLeftGreaterOrEqualInner;
@@ -73,3 +73,6 @@ export const isEqualInner = ({ left, right }) => {
73
73
  export const isLeftGreaterInner = ({ left, right }) => {
74
74
  return compareInner(left, right)[1] > 0;
75
75
  };
76
+ export const isLeftGreaterOrEqualInner = ({ left, right }) => {
77
+ return compareInner(left, right)[1] >= 0;
78
+ };
@@ -1,12 +1,13 @@
1
1
  import type { BI2S } from "../shared/types.d.ts";
2
+ /** Using this function you can chain operations (add, sub, div, mul). */
2
3
  export declare class Pipe {
3
4
  #private;
4
- constructor();
5
+ constructor(value?: string);
5
6
  add(array: string[]): Pipe;
6
7
  sub(array: string[]): Pipe;
7
8
  div(array: string[], limit?: number): Pipe;
8
9
  mul(array: string[]): Pipe;
10
+ abs(): Pipe;
9
11
  calc(): ReturnType<BI2S>;
12
+ resultToBase(radix: number): string;
10
13
  }
11
- /** Using this function you can chain operations (add, sub, div, mul). */
12
- export declare const pipe: Pipe;
package/src/pipe/main.js CHANGED
@@ -1,20 +1,23 @@
1
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
- };
6
1
  var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
7
2
  if (kind === "m") throw new TypeError("Private method is not writable");
8
3
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
9
4
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
10
5
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
11
6
  };
7
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
+ };
12
12
  var _Pipe_result;
13
13
  import { bi2s, calcInner, s2bi } from "../shared/utils.js";
14
14
  import { divInner } from "../operations/div/utils.js";
15
+ import { absInner } from "../abs/utils.js";
16
+ /** Using this function you can chain operations (add, sub, div, mul). */
15
17
  export class Pipe {
16
- constructor() {
18
+ constructor(value) {
17
19
  _Pipe_result.set(this, void 0);
20
+ value && (__classPrivateFieldSet(this, _Pipe_result, s2bi(value), "f"));
18
21
  }
19
22
  add(array) {
20
23
  const arrayInner = array.map((str) => s2bi(str));
@@ -36,14 +39,29 @@ export class Pipe {
36
39
  __classPrivateFieldSet(this, _Pipe_result, calcInner(arrayInner, (a, b) => a * b, __classPrivateFieldGet(this, _Pipe_result, "f")), "f");
37
40
  return this;
38
41
  }
42
+ abs() {
43
+ if (!__classPrivateFieldGet(this, _Pipe_result, "f")) {
44
+ throw new Error("Cannot calculate the absolute value of an undefined.");
45
+ }
46
+ __classPrivateFieldSet(this, _Pipe_result, absInner(__classPrivateFieldGet(this, _Pipe_result, "f")), "f");
47
+ return this;
48
+ }
39
49
  calc() {
50
+ if (!__classPrivateFieldGet(this, _Pipe_result, "f")) {
51
+ throw new Error("Cannot calculate based on an undefined input.");
52
+ }
53
+ const [bi, fpe] = __classPrivateFieldGet(this, _Pipe_result, "f");
54
+ return bi2s(bi, fpe);
55
+ }
56
+ resultToBase(radix) {
40
57
  var _a;
41
- const [bi, fpe] = (_a = __classPrivateFieldGet(this, _Pipe_result, "f")) !== null && _a !== void 0 ? _a : [0n, 0];
42
- const result = bi2s(bi, fpe);
43
- __classPrivateFieldSet(this, _Pipe_result, undefined, "f");
44
- return result;
58
+ if (!__classPrivateFieldGet(this, _Pipe_result, "f")) {
59
+ throw new Error(`Cannot convert an undefined result to base ${radix}.`);
60
+ }
61
+ if (__classPrivateFieldGet(this, _Pipe_result, "f")[1] > 0) {
62
+ throw new Error(`Cannot convert non integer result to base ${radix}.`);
63
+ }
64
+ return (_a = __classPrivateFieldGet(this, _Pipe_result, "f")) === null || _a === void 0 ? void 0 : _a[0].toString(radix);
45
65
  }
46
66
  }
47
67
  _Pipe_result = new WeakMap();
48
- /** Using this function you can chain operations (add, sub, div, mul). */
49
- export const pipe = new Pipe();
package/src/sqrt/main.js CHANGED
@@ -2,9 +2,8 @@ import { round } from "../round/main.js";
2
2
  import { bi2s, s2bi } from "../shared/utils.js";
3
3
  import { sqrtInner } from "./utils.js";
4
4
  /** Find square root of a number */
5
- export const sqrt = (str, precision) => {
6
- const inputInner = s2bi(str);
7
- const [[bi, fpe], decimals] = sqrtInner(inputInner, precision ? s2bi(precision) : undefined);
8
- const outputStr = bi2s(bi, fpe);
9
- return round(outputStr, { decimals });
5
+ export const sqrt = (value, precision) => {
6
+ const valueInner = s2bi(value);
7
+ const [[bi, fpe], decimals] = sqrtInner(valueInner, precision ? s2bi(precision) : undefined);
8
+ return round(bi2s(bi, fpe), { decimals });
10
9
  };
@@ -1,3 +1,3 @@
1
1
  import type { BI } from "../shared/types.d.ts";
2
- export type SqrtInner = (input: BI, prec?: BI, max?: number) => [BI, number];
3
- export type Sqrt = (str: string, precision?: string) => string;
2
+ export type SqrtInner = (value: BI, prec?: BI, max?: number) => [BI, number];
3
+ export type Sqrt = (value: string, precision?: string) => string;
package/src/sqrt/utils.js CHANGED
@@ -1,14 +1,12 @@
1
1
  import { isLeftGreaterInner } from "../compare/utils.js";
2
2
  import { PipeInner } from "../pipe/utils.js";
3
- const halfInner = [5n, 1];
4
- const precDef = [1n, 13];
5
- export const sqrtInner = (input, prec = precDef, max = 100) => {
6
- let guess = input;
3
+ export const sqrtInner = (value, prec = [1n, 13], max = 100) => {
4
+ let guess = value;
7
5
  for (let i = 0; i < max; i++) {
8
6
  const nextGuess = new PipeInner()
9
- .div([input, guess])
7
+ .div([value, guess])
10
8
  .add([guess])
11
- .mul([halfInner])
9
+ .mul([[5n, 1]])
12
10
  .calc();
13
11
  let [bi, fpe] = new PipeInner().sub([nextGuess, guess]).calc();
14
12
  if (bi < 0n)
@@ -0,0 +1,2 @@
1
+ import type { ToBase } from "./types.d.ts";
2
+ export declare const toBase: ToBase;
@@ -0,0 +1,3 @@
1
+ export const toBase = ({ value, toBase }) => {
2
+ return BigInt(value).toString(toBase);
3
+ };
@@ -0,0 +1,4 @@
1
+ export type ToBase = (arg: {
2
+ value: string;
3
+ toBase: number;
4
+ }) => string;