atomic-fns 0.3.5 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/README.md +1 -12
  2. package/{core → dist}/collections/BTree.d.ts +6 -6
  3. package/{core → dist}/collections/BTree.js +17 -17
  4. package/{core → dist}/collections/Heap.d.ts +3 -3
  5. package/{core → dist}/collections/Heap.js +0 -0
  6. package/dist/collections/LRUCache.d.ts +80 -0
  7. package/dist/collections/LRUCache.js +126 -0
  8. package/{core → dist}/collections/SortedMap.d.ts +2 -2
  9. package/{core → dist}/collections/SortedMap.js +0 -0
  10. package/{core → dist}/collections/SortedSet.d.ts +3 -3
  11. package/{core → dist}/collections/SortedSet.js +1 -1
  12. package/{core → dist}/collections/SortedTree.d.ts +3 -3
  13. package/{core → dist}/collections/SortedTree.js +1 -1
  14. package/{core → dist}/collections/SplayTree.d.ts +5 -5
  15. package/{core → dist}/collections/SplayTree.js +0 -0
  16. package/{core → dist}/collections/abc.d.ts +0 -0
  17. package/{core → dist}/collections/abc.js +0 -0
  18. package/{core → dist}/collections/deque.d.ts +7 -7
  19. package/{core → dist}/collections/deque.js +6 -8
  20. package/{core → dist}/collections/frozenset.d.ts +0 -0
  21. package/{core → dist}/collections/frozenset.js +3 -6
  22. package/{core → dist}/collections/index.d.ts +207 -105
  23. package/{core → dist}/collections/index.js +179 -436
  24. package/{core → dist}/functools/index.d.ts +30 -16
  25. package/{core → dist}/functools/index.js +34 -12
  26. package/dist/globals/decimal.d.ts +142 -0
  27. package/dist/globals/decimal.js +371 -0
  28. package/{core → dist}/globals/index.d.ts +26 -25
  29. package/{core → dist}/globals/index.js +16 -37
  30. package/dist/i18n/currency.d.ts +24 -0
  31. package/dist/i18n/currency.js +85 -0
  32. package/dist/i18n/date/index.d.ts +204 -0
  33. package/dist/i18n/date/index.js +530 -0
  34. package/dist/i18n/date/utils.d.ts +65 -0
  35. package/dist/i18n/date/utils.js +290 -0
  36. package/dist/i18n/duration.d.ts +112 -0
  37. package/dist/i18n/duration.js +392 -0
  38. package/dist/i18n/format.d.ts +26 -0
  39. package/dist/i18n/format.js +495 -0
  40. package/{core → dist}/i18n/index.d.ts +2 -1
  41. package/{core → dist}/i18n/index.js +2 -1
  42. package/{core → dist}/index.d.ts +0 -0
  43. package/{core → dist}/index.js +0 -0
  44. package/{core → dist}/itertools/index.d.ts +74 -46
  45. package/{core → dist}/itertools/index.js +28 -56
  46. package/{core → dist}/math/index.d.ts +9 -10
  47. package/{core → dist}/math/index.js +3 -1
  48. package/{core → dist}/operators/index.d.ts +4 -4
  49. package/{core → dist}/operators/index.js +2 -8
  50. package/{core → dist}/random/index.d.ts +1 -1
  51. package/{core → dist}/random/index.js +5 -5
  52. package/package.json +28 -42
  53. package/.editorconfig +0 -12
  54. package/.esdoc.json +0 -27
  55. package/.eslintignore +0 -1
  56. package/.eslintrc.json +0 -35
  57. package/.firebaserc +0 -5
  58. package/.prettierrc +0 -19
  59. package/core/collections/BTree.ts +0 -1340
  60. package/core/collections/Heap.ts +0 -189
  61. package/core/collections/LRUCache.d.ts +0 -152
  62. package/core/collections/LRUCache.js +0 -409
  63. package/core/collections/LRUCache.ts +0 -486
  64. package/core/collections/SortedMap.ts +0 -146
  65. package/core/collections/SortedSet.ts +0 -110
  66. package/core/collections/SortedTree.ts +0 -160
  67. package/core/collections/SplayTree.ts +0 -354
  68. package/core/collections/abc.ts +0 -176
  69. package/core/collections/deque.ts +0 -338
  70. package/core/collections/frozenset.ts +0 -37
  71. package/core/collections/index.ts +0 -1024
  72. package/core/collections/test.html +0 -10
  73. package/core/collections/typedArrays.d.ts +0 -31
  74. package/core/collections/typedArrays.js +0 -143
  75. package/core/collections/typedArrays.ts +0 -163
  76. package/core/functools/index.ts +0 -260
  77. package/core/globals/index.ts +0 -481
  78. package/core/i18n/date/format.d.ts +0 -16
  79. package/core/i18n/date/format.js +0 -307
  80. package/core/i18n/date/format.ts +0 -343
  81. package/core/i18n/date/index.d.ts +0 -224
  82. package/core/i18n/date/index.js +0 -387
  83. package/core/i18n/date/index.ts +0 -471
  84. package/core/i18n/date/test.html +0 -67
  85. package/core/i18n/index.ts +0 -8
  86. package/core/index.ts +0 -8
  87. package/core/itertools/index.ts +0 -494
  88. package/core/math/index.ts +0 -152
  89. package/core/operators/index.ts +0 -310
  90. package/core/random/index.ts +0 -66
  91. package/firebase.json +0 -10
  92. package/jasmine.json +0 -14
  93. package/tests/BTree.spec.ts +0 -143
  94. package/tests/Cache.spec.ts +0 -161
  95. package/tests/Heap.spec.ts +0 -66
  96. package/tests/SortedMap.spec.ts +0 -144
  97. package/tests/SortedSet.spec.ts +0 -84
  98. package/tests/SortedTree.spec.ts +0 -164
  99. package/tests/SplayTree.spec.ts +0 -121
  100. package/tests/collections.spec.ts +0 -288
  101. package/tests/deque.spec.ts +0 -107
  102. package/tests/globals.spec.ts +0 -270
  103. package/tests/itertools.spec.ts +0 -266
  104. package/tests/math.spec.ts +0 -25
  105. package/tests/operators.spec.ts +0 -40
  106. package/tests/random.spec.ts +0 -46
  107. package/tsconfig.json +0 -126
  108. package/tsconfig.node.json +0 -18
  109. package/tsconfig.xo.json +0 -9
@@ -12,7 +12,7 @@ import { Function } from '../globals/index.js';
12
12
  * @returns {Function} Returns the new bound function.
13
13
  * @see {@link partial}
14
14
  */
15
- export declare const bind: (fn: Function, thisArg: any, ...partials: any[]) => (...args: any[]) => any;
15
+ export declare const bind: (fn: Function, thisArg: any, ...partials: any[]) => any;
16
16
  /**
17
17
  * Creates a function that accepts arguments of `func` and either invokes `func` returning its result, if at least arity number of arguments have been provided, or returns a function that accepts the remaining `func` arguments, and so on. The arity of `func` may be specified if `func.length` is not sufficient.
18
18
  * @param {Function} func The function to curry.
@@ -27,7 +27,7 @@ export declare const curry: (func: Function, arity?: number) => Function<any>;
27
27
  * @param {...*} [args] The arguments to apply to `fn`.
28
28
  * @returns {Function} Returns the new partially applied function
29
29
  */
30
- export declare const partial: (fn: any, ...args: any[]) => (...args: any[]) => any;
30
+ export declare const partial: (fn: any, ...args: any[]) => any;
31
31
  /**
32
32
  * Creates a function composition from a given set of functions that will be each applied on the result of the previous one from left to right.
33
33
  * @param {...*} [args] The set of functions to apply.
@@ -47,7 +47,15 @@ export declare const compose: (...args: any[]) => (x: any) => any;
47
47
  * @param {Function} [resolver] The function to resolve the cache key.
48
48
  * @return {Function} Returns the new memoized function.
49
49
  */
50
- export declare function memoize<T>(func: Function<T>, resolver?: Function): Function<ReturnType<typeof func>>;
50
+ export declare function memoize<T>(func: Function<T>, resolver?: Function): Function<T>;
51
+ /**
52
+ * Can be used as a decorator on any function or method to memoize its results.
53
+ * **NOTE:** By default the given function is memoized using it's first argument, regardless of others.
54
+ * @param target
55
+ * @param name
56
+ * @param descriptor
57
+ * @returns A memoized version of the given function
58
+ */
51
59
  export declare function cache(target: any, name: any, descriptor: any): any;
52
60
  /**
53
61
  * Creates a debounced function that delays invoking `func` until after `wait` milliseconds have elapsed since the last time the debounced function was invoked. Subsequent calls to the debounced function return the result of the last successful invocation. Provide options to set the `maxWait` milliseconds, regardless of when the function was last invoked.
@@ -77,32 +85,38 @@ export declare function throttle(func: Function, wait: number): Function;
77
85
  ```js
78
86
  let func = x => x
79
87
  let single = once(func)
80
- single(1) // => 1
81
- single(2) // => 1
82
- single(3) // => 1
88
+ single(1) // 1
89
+ single(2) // 1
90
+ single(3) // 1
83
91
  // ...
84
- // => `func` is invoked only once.
92
+ // `func` is invoked only once.
85
93
  ```
86
94
  */
87
- export declare function once<T>(func: Function<T>): (...args: any[]) => T;
95
+ export declare function once<T>(func: Function<T>): Function<T>;
88
96
  export declare type Maybe<T> = T | undefined;
89
97
  export declare type Result<T, E = any> = [Maybe<T>, Maybe<E>];
90
98
  export declare type Optional<T> = Maybe<T>;
91
99
  /**
92
100
  * Wraps a function to catch any exceptions inside and return a `go` style error-return type {@link Result}.
93
- *
101
+ * @template T,E
94
102
  * @param {Function} fun The function to wrap and catch if it throws.
95
- * @param {?function(err: E, res: T): *} [onFinally] Optional callback that will be called on the `finally` clause if given.
103
+ * @param {Function} [onFinally] Optional callback that will be invoked with `(err?, value)` on the `finally` clause.
96
104
  * @returns {Function} A new function that wraps `fun`.
97
- * @template T,E
98
105
  */
99
106
  export declare function result<T = any, E = unknown>(fun: Function<T>, onFinally?: (err: E, res: T) => any): (...args: any[]) => Result<T, E>;
100
107
  /**
101
108
  * Wraps a function or promise to catch any exceptions inside and return a `go` style error-return type. This is like {@link result} but it deals with async functions or promises.
102
- *
103
- * @param {Function|Promise} awaitable The function or promise to await.
104
- * @param {?function(err: E, res: T): *} [onFinally] Optional callback that will be called on the `finally` clause if given.
105
- * @returns {Function} A new function that awaits the `awaitable` param and returns a {@link Result} type.
106
109
  * @template T,E
110
+ * @param {Function<T>|Promise<T>} awaitable The function or promise to await.
111
+ * @param {Function} [onFinally] Optional callback that will be invoked with `(err?, value)` on the `finally` clause.
112
+ * @returns {Function<Promise<Result<T, E>>>} A new function that awaits the `awaitable` param and returns a {@link Result} type.
113
+ */
114
+ export declare function resultAsync<T = any, E = unknown>(awaitable: Promise<T> | Function<Promise<T>>, onFinally?: (err: E, res: T) => any): (...args: any[]) => Promise<any[]>;
115
+ /**
116
+ * Converts a function that expects a node-style callback argument like `(err, result)` to return a Promise instead.
117
+ * @template T
118
+ * @param {Function<T>} fun The given function to convert from callback style to Promise.
119
+ * @param {*} thisArg
120
+ * @returns {Function<Promise<T>>} A function that wraps `fun` and returns a Promise.
107
121
  */
108
- export declare function resultAsync<T = any, E = unknown>(awaitable: Promise<T> | Function<Promise<T>>, onFinally?: (err: E, res: T) => any): (...args: any[]) => Promise<Result<T, E>>;
122
+ export declare function promisify<T>(fun: Function, thisArg?: any): Function<Promise<T>>;
@@ -89,7 +89,14 @@ export function memoize(func, resolver) {
89
89
  return value;
90
90
  };
91
91
  }
92
- // TODO: also sized lru_cache
92
+ /**
93
+ * Can be used as a decorator on any function or method to memoize its results.
94
+ * **NOTE:** By default the given function is memoized using it's first argument, regardless of others.
95
+ * @param target
96
+ * @param name
97
+ * @param descriptor
98
+ * @returns A memoized version of the given function
99
+ */
93
100
  export function cache(target, name, descriptor) {
94
101
  const original = descriptor.value;
95
102
  if (typeof original === 'function') {
@@ -153,11 +160,11 @@ export function throttle(func, wait) {
153
160
  ```js
154
161
  let func = x => x
155
162
  let single = once(func)
156
- single(1) // => 1
157
- single(2) // => 1
158
- single(3) // => 1
163
+ single(1) // 1
164
+ single(2) // 1
165
+ single(3) // 1
159
166
  // ...
160
- // => `func` is invoked only once.
167
+ // `func` is invoked only once.
161
168
  ```
162
169
  */
163
170
  export function once(func) {
@@ -172,11 +179,10 @@ export function once(func) {
172
179
  }
173
180
  /**
174
181
  * Wraps a function to catch any exceptions inside and return a `go` style error-return type {@link Result}.
175
- *
182
+ * @template T,E
176
183
  * @param {Function} fun The function to wrap and catch if it throws.
177
- * @param {?function(err: E, res: T): *} [onFinally] Optional callback that will be called on the `finally` clause if given.
184
+ * @param {Function} [onFinally] Optional callback that will be invoked with `(err?, value)` on the `finally` clause.
178
185
  * @returns {Function} A new function that wraps `fun`.
179
- * @template T,E
180
186
  */
181
187
  export function result(fun, onFinally) {
182
188
  return (...args) => {
@@ -195,11 +201,10 @@ export function result(fun, onFinally) {
195
201
  }
196
202
  /**
197
203
  * Wraps a function or promise to catch any exceptions inside and return a `go` style error-return type. This is like {@link result} but it deals with async functions or promises.
198
- *
199
- * @param {Function|Promise} awaitable The function or promise to await.
200
- * @param {?function(err: E, res: T): *} [onFinally] Optional callback that will be called on the `finally` clause if given.
201
- * @returns {Function} A new function that awaits the `awaitable` param and returns a {@link Result} type.
202
204
  * @template T,E
205
+ * @param {Function<T>|Promise<T>} awaitable The function or promise to await.
206
+ * @param {Function} [onFinally] Optional callback that will be invoked with `(err?, value)` on the `finally` clause.
207
+ * @returns {Function<Promise<Result<T, E>>>} A new function that awaits the `awaitable` param and returns a {@link Result} type.
203
208
  */
204
209
  export function resultAsync(awaitable, onFinally) {
205
210
  return async (...args) => {
@@ -217,3 +222,20 @@ export function resultAsync(awaitable, onFinally) {
217
222
  return [value, err];
218
223
  };
219
224
  }
225
+ /**
226
+ * Converts a function that expects a node-style callback argument like `(err, result)` to return a Promise instead.
227
+ * @template T
228
+ * @param {Function<T>} fun The given function to convert from callback style to Promise.
229
+ * @param {*} thisArg
230
+ * @returns {Function<Promise<T>>} A function that wraps `fun` and returns a Promise.
231
+ */
232
+ export function promisify(fun, thisArg) {
233
+ const original = thisArg ? fun.bind(thisArg) : fun;
234
+ return async (...args) => {
235
+ return await new Promise((resolve, reject) => original(...args, (err, result) => {
236
+ if (err)
237
+ return reject(err);
238
+ resolve(result);
239
+ }));
240
+ };
241
+ }
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Casts the given value as a {@link Decimal}.
3
+ */
4
+ export declare function decimal(x: any): Decimal;
5
+ /**
6
+ * `Decimal` provides support for correct rounded floating point arithmetic, unlike the standard Number type. It also supports user-defined precision (default is 20 decimal places) which can be as large as needed.
7
+ */
8
+ export declare class Decimal {
9
+ static PRECISION: number;
10
+ i: bigint;
11
+ e: number;
12
+ /**
13
+ * Returns a new `Decimal` instance from the value or `0`.
14
+ * @param {*} value
15
+ * @returns {Decimal}
16
+ */
17
+ constructor(value?: any);
18
+ /**
19
+ * Returns a new `Decimal` that has the opposite sign of this `Decimal`.
20
+ * @example
21
+ ```js
22
+ let a = decimal('5')
23
+ a.minus() // -5
24
+ ```
25
+ * @returns {Decimal}
26
+ */
27
+ negated(): Decimal;
28
+ /**
29
+ * Returns a new `Decimal` that is the sum of this and `x`.
30
+ * @param x
31
+ * @example
32
+ ```js
33
+ let a = decimal('50000000000')
34
+ let b = decimal('0.000000005')
35
+ a.add(b) // 50000000000.000000005
36
+ ```
37
+ * @returns {Decimal}
38
+ */
39
+ add(x: any): Decimal;
40
+ /**
41
+ * Returns a new `Decimal` that is the difference between this and `x`.
42
+ * @param x
43
+ * @example
44
+ ```js
45
+ let a = decimal('1')
46
+ let b = decimal('0.0000000000000000001')
47
+ a.sub(b) // 0.9999999999999999999
48
+ ```
49
+ * @returns {Decimal}
50
+ */
51
+ sub(x: any): Decimal;
52
+ /**
53
+ * Returns a new `Decimal` that is the product of this and `x`.
54
+ * @param x
55
+ * @example
56
+ ```js
57
+ let a = decimal('0.0000000000000000000025')
58
+ let b = decimal('400000000000000000000')
59
+ a.mul(b) // 1
60
+ ```
61
+ * @returns {Decimal}
62
+ */
63
+ mul(x: any): Decimal;
64
+ /**
65
+ * Returns a new `Decimal` that is the quotient of this and `x`
66
+ * @param x
67
+ * @example
68
+ ```js
69
+ let a = decimal('1')
70
+ let b = decimal('3')
71
+ a.div(b) // 0.333333333333333333333333333333
72
+ ```
73
+ * @returns {Decimal}
74
+ */
75
+ div(x: any): Decimal;
76
+ /**
77
+ * Returns the square root of this `Decimal`.
78
+ * @returns {TDecimal}
79
+ */
80
+ sqrt(): Decimal;
81
+ /** Returns a new copy of this Decimal value. */
82
+ clone(): Decimal;
83
+ /**
84
+ * Remove zeroes in the least-significant digit of this `Decimal`
85
+ */
86
+ _normalize(): this;
87
+ /**
88
+ * Truncate this `Decimal` to the configured precision
89
+ */
90
+ _truncate(): this;
91
+ /**
92
+ * Returns a string representation of this decimal.
93
+ * @returns {Decimal}
94
+ */
95
+ toString(): string;
96
+ /**
97
+ * Converts this decimal to the `Number` value
98
+ * @returns {number}
99
+ */
100
+ toNumber(): number;
101
+ static get precision(): number;
102
+ static set precision(value: number);
103
+ /**
104
+ * Returns `true` if this value is equal to the value of `x`, otherwise `false`.
105
+ * @param {*} x other
106
+ * @returns {boolean}
107
+ */
108
+ eq(x: any): boolean;
109
+ /**
110
+ * Returns `true` if this value is less than the value of `x`, otherwise `false`.
111
+ * @param {*} x
112
+ * @returns {boolean}
113
+ */
114
+ lt(x: any): boolean;
115
+ /**
116
+ * Returns a comparison value representing the ordering of this value in respect to `x`.
117
+ * * `-1` if this < x
118
+ * * `1` if this > x
119
+ * * `0` if this == x
120
+ * @param {*} x
121
+ * @returns {number}
122
+ */
123
+ compare(x: any): 1 | -1 | 0;
124
+ /**
125
+ * Returns `true` if this value is greater than the value of `x`, otherwise `false`.
126
+ * @param {*} x
127
+ * @returns {boolean}
128
+ */
129
+ gt(x: any): boolean;
130
+ /**
131
+ * Returns `true` if this value is less than or equal to the value of `x`, otherwise `false`.
132
+ * @param {*} x
133
+ * @returns {boolean}
134
+ */
135
+ lte(x: any): boolean;
136
+ /**
137
+ * Returns `true` if this value is greater than or equal to the value of `x`, otherwise `false`.
138
+ * @param {*} x
139
+ * @returns {boolean}
140
+ */
141
+ gte(x: any): boolean;
142
+ }
@@ -0,0 +1,371 @@
1
+ const NUMBER_REGEX = /^(-?)([0-9]+)(\.([0-9]+))?$/;
2
+ /**
3
+ * Casts the given value as a {@link Decimal}.
4
+ */
5
+ export function decimal(x) {
6
+ return new Decimal(x);
7
+ }
8
+ /**
9
+ * `Decimal` provides support for correct rounded floating point arithmetic, unlike the standard Number type. It also supports user-defined precision (default is 20 decimal places) which can be as large as needed.
10
+ */
11
+ export class Decimal {
12
+ static PRECISION = 20;
13
+ i = 0n;
14
+ e = 0;
15
+ /**
16
+ * Returns a new `Decimal` instance from the value or `0`.
17
+ * @param {*} value
18
+ * @returns {Decimal}
19
+ */
20
+ constructor(value) {
21
+ if (value == null) {
22
+ return this;
23
+ }
24
+ // Check if value is a Decimal like
25
+ if (typeof value?.i === 'bigint' && typeof value.e === 'number') {
26
+ this.i = value.i;
27
+ this.e = value.e;
28
+ this._normalize();
29
+ return this;
30
+ }
31
+ const result = NUMBER_REGEX.exec(value.toString());
32
+ if (result) {
33
+ // console.log(result);
34
+ // Construct from string if possible
35
+ // this.i = parseInt(result[1] + result[2] + result[4]);
36
+ if (typeof result[2] === 'undefined')
37
+ result[2] = '';
38
+ if (typeof result[4] === 'undefined')
39
+ result[4] = '';
40
+ this.i = BigInt(result[1] + result[2] + result[4]);
41
+ this.e = result[4] ? -result[4].length : 0;
42
+ this._normalize();
43
+ }
44
+ else {
45
+ // Conversion to string failed, so construct from number
46
+ let m = 1n;
47
+ if (value < 0) {
48
+ value = -value;
49
+ m = -1n;
50
+ }
51
+ if (value === 0) {
52
+ this.i = 0n;
53
+ this.e = 0;
54
+ }
55
+ else {
56
+ // Multiply the number by 10 until it is an integer
57
+ let e = -Math.floor(Math.log10(value));
58
+ if (e > 0) {
59
+ value *= Math.pow(10, e);
60
+ }
61
+ else {
62
+ e = 0;
63
+ }
64
+ while (value !== Math.round(value)) {
65
+ e++;
66
+ value *= 10;
67
+ }
68
+ // Divide the number by 10 until the one's digit is non-zero
69
+ while (value % 10 === 0 && value > 0) {
70
+ e--;
71
+ value /= 10;
72
+ }
73
+ value = BigInt(value);
74
+ this.i = value * m;
75
+ this.e = -e;
76
+ }
77
+ }
78
+ }
79
+ /**
80
+ * Returns a new `Decimal` that has the opposite sign of this `Decimal`.
81
+ * @example
82
+ ```js
83
+ let a = decimal('5')
84
+ a.minus() // -5
85
+ ```
86
+ * @returns {Decimal}
87
+ */
88
+ negated() {
89
+ const negated = new Decimal();
90
+ negated.i = -this.i;
91
+ negated.e = this.e;
92
+ return negated;
93
+ }
94
+ /**
95
+ * Returns a new `Decimal` that is the sum of this and `x`.
96
+ * @param x
97
+ * @example
98
+ ```js
99
+ let a = decimal('50000000000')
100
+ let b = decimal('0.000000005')
101
+ a.add(b) // 50000000000.000000005
102
+ ```
103
+ * @returns {Decimal}
104
+ */
105
+ add(x) {
106
+ let a = new Decimal(this);
107
+ let b = new Decimal(x);
108
+ // a+b = a.i * 10^a.e + b.i * 10^b.e
109
+ // a+b = ( a.i * 10^(a.e-b.e) + b.i ) * 10^b.e
110
+ const result = new Decimal();
111
+ // Order arguments so that a.e >= b.e
112
+ if (a.e < b.e) {
113
+ const c = a;
114
+ a = b;
115
+ b = c;
116
+ }
117
+ const intPart = exp(a.i, a.e - b.e);
118
+ result.i = intPart + b.i;
119
+ result.e = b.e;
120
+ result._normalize();
121
+ return result;
122
+ }
123
+ /**
124
+ * Returns a new `Decimal` that is the difference between this and `x`.
125
+ * @param x
126
+ * @example
127
+ ```js
128
+ let a = decimal('1')
129
+ let b = decimal('0.0000000000000000001')
130
+ a.sub(b) // 0.9999999999999999999
131
+ ```
132
+ * @returns {Decimal}
133
+ */
134
+ sub(x) {
135
+ return this.add(decimal(x).negated());
136
+ }
137
+ /**
138
+ * Returns a new `Decimal` that is the product of this and `x`.
139
+ * @param x
140
+ * @example
141
+ ```js
142
+ let a = decimal('0.0000000000000000000025')
143
+ let b = decimal('400000000000000000000')
144
+ a.mul(b) // 1
145
+ ```
146
+ * @returns {Decimal}
147
+ */
148
+ mul(x) {
149
+ const a = new Decimal(this);
150
+ const b = new Decimal(x);
151
+ // a * b = (a.i * b.i) * 10^(a.e + b.e)
152
+ const result = new Decimal();
153
+ result.i = a.i * b.i;
154
+ result.e = a.e + b.e;
155
+ result._normalize();
156
+ return result;
157
+ }
158
+ /**
159
+ * Returns a new `Decimal` that is the quotient of this and `x`
160
+ * @param x
161
+ * @example
162
+ ```js
163
+ let a = decimal('1')
164
+ let b = decimal('3')
165
+ a.div(b) // 0.333333333333333333333333333333
166
+ ```
167
+ * @returns {Decimal}
168
+ */
169
+ div(x) {
170
+ const a = new Decimal(this);
171
+ const b = new Decimal(x);
172
+ // We need to increase the number of digits of a and b so that a / b will have the desired precision.
173
+ // In order for the integer quotient to have the correct precision, a.e - b.e must be greater than that precision.
174
+ // So we need only to increase a.e.
175
+ // TODO: Revisit the value of increaseA. Is it correct in every circumstance?
176
+ const increaseA = Math.max(Decimal.precision - (a.e + b.e), 0);
177
+ const intIncrease = new Decimal();
178
+ intIncrease.i = exp(a.i, increaseA);
179
+ const quotient = new Decimal();
180
+ quotient.i = intIncrease.i / b.i;
181
+ quotient.e = a.e - b.e - increaseA;
182
+ // No need to truncate since we already increased the number of digits before dividing
183
+ quotient._normalize();
184
+ return quotient;
185
+ }
186
+ /**
187
+ * Returns the square root of this `Decimal`.
188
+ * @returns {TDecimal}
189
+ */
190
+ sqrt() {
191
+ Decimal.PRECISION++;
192
+ // Let the guess value be 10^(e/2), where e is this.e
193
+ let x = new Decimal();
194
+ x.i = 1n;
195
+ x.e = Math.floor(this.e / 2);
196
+ const onehalf = new Decimal('0.5');
197
+ let xt = x.clone();
198
+ xt._truncate();
199
+ xt._normalize();
200
+ let lastxt;
201
+ let i;
202
+ for (i = 0; i < 100; i++) {
203
+ lastxt = xt;
204
+ x = this.div(x).add(x).mul(onehalf);
205
+ xt = x.clone();
206
+ xt._truncate();
207
+ xt._normalize();
208
+ if (xt.i === lastxt.i && xt.e === lastxt.e)
209
+ break;
210
+ }
211
+ if (i >= 100) {
212
+ console.log('Warning: sqrt exceeded maximum iterations. (Did it enter a cycle?)');
213
+ }
214
+ Decimal.PRECISION--;
215
+ xt._truncate();
216
+ xt._normalize();
217
+ return xt;
218
+ }
219
+ /** Returns a new copy of this Decimal value. */
220
+ clone() {
221
+ const a = new Decimal();
222
+ a.i = this.i;
223
+ a.e = this.e;
224
+ return a;
225
+ }
226
+ /**
227
+ * Remove zeroes in the least-significant digit of this `Decimal`
228
+ */
229
+ _normalize() {
230
+ while (this.i % 10n === 0n && this.i !== 0n) {
231
+ this.i /= 10n;
232
+ this.e++;
233
+ }
234
+ return this;
235
+ }
236
+ /**
237
+ * Truncate this `Decimal` to the configured precision
238
+ */
239
+ _truncate() {
240
+ // TODO: Make this better
241
+ // TODO: Rounding
242
+ const trunc = -this.e - Decimal.PRECISION;
243
+ if (trunc > 0) {
244
+ this.i /= 10n ** BigInt(trunc - 1);
245
+ this.e += trunc;
246
+ const nextDigit = this.i % 10n;
247
+ if (nextDigit >= 5) {
248
+ this.i += 10n;
249
+ }
250
+ this.i /= 10n;
251
+ }
252
+ // while(-this.e > Decimal.PRECISION) {
253
+ // this.i /= 10n;
254
+ // this.e++;
255
+ // }
256
+ return this;
257
+ }
258
+ /**
259
+ * Returns a string representation of this decimal.
260
+ * @returns {Decimal}
261
+ */
262
+ toString() {
263
+ let s = this.i.toString();
264
+ let m = '';
265
+ if (s[0] === '-') {
266
+ s = s.substring(1, s.length);
267
+ m = '-';
268
+ }
269
+ if (this.e > 0) {
270
+ return m + s + '0'.repeat(this.e);
271
+ }
272
+ else if (this.e < 0) {
273
+ if (-this.e >= s.length) {
274
+ return m + '0.' + '0'.repeat(-this.e - s.length) + s;
275
+ }
276
+ return m + s.slice(0, s.length + this.e) + '.' + s.slice(s.length + this.e, s.length);
277
+ }
278
+ else {
279
+ return m + s;
280
+ }
281
+ }
282
+ [Symbol.for('nodejs.util.inspect.custom')]() {
283
+ return this.toString();
284
+ }
285
+ /**
286
+ * Converts this decimal to the `Number` value
287
+ * @returns {number}
288
+ */
289
+ toNumber() {
290
+ return Number(Decimal.prototype.toString.call(this));
291
+ }
292
+ static get precision() {
293
+ return Decimal.PRECISION;
294
+ }
295
+ static set precision(value) {
296
+ Decimal.PRECISION = value;
297
+ }
298
+ /**
299
+ * Returns `true` if this value is equal to the value of `x`, otherwise `false`.
300
+ * @param {*} x other
301
+ * @returns {boolean}
302
+ */
303
+ eq(x) {
304
+ const other = decimal(x);
305
+ return this.i === other.i && this.e === other.e;
306
+ }
307
+ /**
308
+ * Returns `true` if this value is less than the value of `x`, otherwise `false`.
309
+ * @param {*} x
310
+ * @returns {boolean}
311
+ */
312
+ lt(x) {
313
+ const other = decimal(x);
314
+ if (this.e === other.e)
315
+ return this.i < other.i;
316
+ const e = this.e - other.e;
317
+ if (e > 0) {
318
+ return exp(this.i, e) < other.i;
319
+ }
320
+ return this.i < exp(other.i, -e);
321
+ }
322
+ /**
323
+ * Returns a comparison value representing the ordering of this value in respect to `x`.
324
+ * * `-1` if this < x
325
+ * * `1` if this > x
326
+ * * `0` if this == x
327
+ * @param {*} x
328
+ * @returns {number}
329
+ */
330
+ compare(x) {
331
+ if (this.eq(x))
332
+ return 0;
333
+ if (this.lt(x))
334
+ return -1;
335
+ return 1;
336
+ }
337
+ /**
338
+ * Returns `true` if this value is greater than the value of `x`, otherwise `false`.
339
+ * @param {*} x
340
+ * @returns {boolean}
341
+ */
342
+ gt(x) {
343
+ return this.compare(x) > 0;
344
+ }
345
+ /**
346
+ * Returns `true` if this value is less than or equal to the value of `x`, otherwise `false`.
347
+ * @param {*} x
348
+ * @returns {boolean}
349
+ */
350
+ lte(x) {
351
+ return this.compare(x) <= 0;
352
+ }
353
+ /**
354
+ * Returns `true` if this value is greater than or equal to the value of `x`, otherwise `false`.
355
+ * @param {*} x
356
+ * @returns {boolean}
357
+ */
358
+ gte(x) {
359
+ return this.compare(x) >= 0;
360
+ }
361
+ }
362
+ /** Returns a BigInt that is equal to `i` times `10^e` */
363
+ function exp(i, e) {
364
+ // TODO: Make this better
365
+ // The implementation is faster than 10n ** BigInt(e). But could we make it faster still?
366
+ let ii = i;
367
+ for (let j = 0; j < e; j++) {
368
+ ii *= 10n;
369
+ }
370
+ return ii;
371
+ }