atomic-fns 1.2.0 → 2.0.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 +397 -91
- package/dist/array/index.d.ts +9 -0
- package/dist/array/index.js +9 -0
- package/dist/array/list.d.ts +99 -0
- package/dist/array/list.js +133 -0
- package/dist/array/sets.d.ts +130 -0
- package/dist/array/sets.js +213 -0
- package/dist/async/index.d.ts +6 -0
- package/dist/async/index.js +6 -0
- package/dist/async/retry.d.ts +38 -0
- package/dist/async/retry.js +56 -0
- package/dist/async/sleep.d.ts +42 -0
- package/dist/async/sleep.js +76 -0
- package/dist/collections/bisect.d.ts +103 -0
- package/dist/collections/bisect.js +157 -0
- package/dist/collections/deque.d.ts +67 -97
- package/dist/collections/deque.js +197 -256
- package/dist/collections/entries.d.ts +89 -0
- package/dist/collections/entries.js +131 -0
- package/dist/collections/frozen-set.d.ts +42 -0
- package/dist/collections/frozen-set.js +64 -0
- package/dist/collections/group.d.ts +141 -0
- package/dist/collections/group.js +241 -0
- package/dist/collections/heap.d.ts +64 -0
- package/dist/collections/heap.js +205 -0
- package/dist/collections/index.d.ts +15 -623
- package/dist/collections/index.js +14 -844
- package/dist/collections/internal/arrayKeys.d.ts +19 -0
- package/dist/collections/internal/arrayKeys.js +83 -0
- package/dist/collections/internal/invariants.d.ts +4 -0
- package/dist/collections/internal/invariants.js +12 -0
- package/dist/collections/internal/iterable.d.ts +25 -0
- package/dist/collections/internal/iterable.js +62 -0
- package/dist/collections/iterate.d.ts +162 -0
- package/dist/collections/iterate.js +188 -0
- package/dist/collections/lru-cache.d.ts +58 -0
- package/dist/collections/lru-cache.js +164 -0
- package/dist/collections/order.d.ts +19 -0
- package/dist/collections/order.js +38 -0
- package/dist/collections/shape.d.ts +32 -0
- package/dist/collections/shape.js +86 -0
- package/dist/collections/sorted-map.d.ts +171 -0
- package/dist/collections/sorted-map.js +845 -0
- package/dist/collections/sorted-set.d.ts +103 -0
- package/dist/collections/sorted-set.js +147 -0
- package/dist/collections/splay-tree.d.ts +82 -0
- package/dist/collections/splay-tree.js +354 -0
- package/dist/collections/trie.d.ts +58 -0
- package/dist/collections/trie.js +196 -0
- package/dist/decimal/currency.d.ts +211 -0
- package/dist/decimal/currency.js +321 -0
- package/dist/decimal/decimal.d.ts +299 -0
- package/dist/decimal/decimal.js +660 -0
- package/dist/decimal/index.d.ts +11 -148
- package/dist/decimal/index.js +10 -410
- package/dist/decimal/internal/bits.d.ts +2 -0
- package/dist/decimal/internal/bits.js +7 -0
- package/dist/decimal/internal/echo.d.ts +4 -0
- package/dist/decimal/internal/echo.js +6 -0
- package/dist/decimal/internal/isqrt.d.ts +9 -0
- package/dist/decimal/internal/isqrt.js +34 -0
- package/dist/decimal/internal/locale.d.ts +7 -0
- package/dist/decimal/internal/locale.js +24 -0
- package/dist/decimal/internal/minor-units.d.ts +2 -0
- package/dist/decimal/internal/minor-units.js +33 -0
- package/dist/decimal/internal/pow10.d.ts +24 -0
- package/dist/decimal/internal/pow10.js +96 -0
- package/dist/encoding/base64.d.ts +39 -0
- package/dist/encoding/base64.js +53 -0
- package/dist/encoding/hex.d.ts +23 -0
- package/dist/encoding/hex.js +34 -0
- package/dist/encoding/index.d.ts +6 -0
- package/dist/encoding/index.js +6 -0
- package/dist/function/debounce.d.ts +68 -0
- package/dist/function/debounce.js +203 -0
- package/dist/function/index.d.ts +6 -0
- package/dist/function/index.js +6 -0
- package/dist/function/shared.d.ts +2 -0
- package/dist/function/shared.js +5 -0
- package/dist/function/wrap.d.ts +130 -0
- package/dist/function/wrap.js +113 -0
- package/dist/hash/digest.d.ts +18 -0
- package/dist/hash/digest.js +26 -0
- package/dist/hash/hash.d.ts +22 -0
- package/dist/hash/hash.js +252 -0
- package/dist/hash/hashString.d.ts +13 -0
- package/dist/hash/hashString.js +53 -0
- package/dist/hash/index.d.ts +8 -0
- package/dist/hash/index.js +8 -0
- package/dist/hash/stableStringify.d.ts +19 -0
- package/dist/hash/stableStringify.js +102 -0
- package/dist/id/index.d.ts +7 -0
- package/dist/id/index.js +7 -0
- package/dist/id/nanoid.d.ts +16 -0
- package/dist/id/nanoid.js +65 -0
- package/dist/id/uniqueId.d.ts +14 -0
- package/dist/id/uniqueId.js +20 -0
- package/dist/id/uuid.d.ts +25 -0
- package/dist/id/uuid.js +64 -0
- package/dist/index.d.ts +15 -8
- package/dist/index.js +15 -8
- package/dist/internal/bytes.d.ts +11 -0
- package/dist/internal/bytes.js +33 -0
- package/dist/internal/codec.d.ts +11 -0
- package/dist/internal/codec.js +84 -0
- package/dist/internal/compare.d.ts +10 -0
- package/dist/internal/compare.js +26 -0
- package/dist/internal/crypto.d.ts +5 -0
- package/dist/internal/crypto.js +11 -0
- package/dist/internal/keys.d.ts +12 -0
- package/dist/internal/keys.js +23 -0
- package/dist/internal/kind.d.ts +44 -0
- package/dist/internal/kind.js +139 -0
- package/dist/internal/sparse.d.ts +51 -0
- package/dist/internal/sparse.js +104 -0
- package/dist/internal/text.d.ts +7 -0
- package/dist/internal/text.js +15 -0
- package/dist/internal/timer.d.ts +10 -0
- package/dist/internal/timer.js +17 -0
- package/dist/internal/truncate.d.ts +10 -0
- package/dist/internal/truncate.js +22 -0
- package/dist/internal/walk.d.ts +47 -0
- package/dist/internal/walk.js +100 -0
- package/dist/is/index.d.ts +8 -0
- package/dist/is/index.js +8 -0
- package/dist/is/isArrayLike.d.ts +18 -0
- package/dist/is/isArrayLike.js +25 -0
- package/dist/is/isError.d.ts +13 -0
- package/dist/is/isError.js +18 -0
- package/dist/is/isNil.d.ts +12 -0
- package/dist/is/isNil.js +14 -0
- package/dist/is/isPlainObject.d.ts +15 -0
- package/dist/is/isPlainObject.js +34 -0
- package/dist/number/index.d.ts +7 -0
- package/dist/number/index.js +7 -0
- package/dist/number/round.d.ts +86 -0
- package/dist/number/round.js +130 -0
- package/dist/number/stats.d.ts +52 -0
- package/dist/number/stats.js +115 -0
- package/dist/object/cloneDeep.d.ts +28 -0
- package/dist/object/cloneDeep.js +200 -0
- package/dist/object/index.d.ts +14 -0
- package/dist/object/index.js +13 -0
- package/dist/object/isEqual.d.ts +64 -0
- package/dist/object/isEqual.js +289 -0
- package/dist/object/matches.d.ts +40 -0
- package/dist/object/matches.js +284 -0
- package/dist/object/merge.d.ts +66 -0
- package/dist/object/merge.js +272 -0
- package/dist/object/parsePath.d.ts +22 -0
- package/dist/object/parsePath.js +111 -0
- package/dist/object/path.d.ts +85 -0
- package/dist/object/path.js +208 -0
- package/dist/object/pick.d.ts +91 -0
- package/dist/object/pick.js +180 -0
- package/dist/object/reshape.d.ts +73 -0
- package/dist/object/reshape.js +144 -0
- package/dist/random/index.d.ts +96 -32
- package/dist/random/index.js +215 -53
- package/dist/string/case.d.ts +71 -0
- package/dist/string/case.js +152 -0
- package/dist/string/fold.d.ts +35 -0
- package/dist/string/fold.js +100 -0
- package/dist/string/index.d.ts +6 -187
- package/dist/string/index.js +6 -224
- package/dist/string/truncate.d.ts +25 -0
- package/dist/string/truncate.js +44 -0
- package/dist/string/words.d.ts +27 -0
- package/dist/string/words.js +241 -0
- package/package.json +99 -51
- package/dist/collections/BTree.d.ts +0 -230
- package/dist/collections/BTree.js +0 -1143
- package/dist/collections/Heap.d.ts +0 -69
- package/dist/collections/Heap.js +0 -181
- package/dist/collections/LRUCache.d.ts +0 -83
- package/dist/collections/LRUCache.js +0 -139
- package/dist/collections/SortedMap.d.ts +0 -92
- package/dist/collections/SortedMap.js +0 -131
- package/dist/collections/SortedSet.d.ts +0 -69
- package/dist/collections/SortedSet.js +0 -99
- package/dist/collections/SortedTree.d.ts +0 -103
- package/dist/collections/SortedTree.js +0 -142
- package/dist/collections/SplayTree.d.ts +0 -107
- package/dist/collections/SplayTree.js +0 -351
- package/dist/collections/Trie.d.ts +0 -42
- package/dist/collections/Trie.js +0 -104
- package/dist/collections/abc.d.ts +0 -152
- package/dist/collections/abc.js +0 -39
- package/dist/collections/frozenset.d.ts +0 -19
- package/dist/collections/frozenset.js +0 -33
- package/dist/functools/index.d.ts +0 -106
- package/dist/functools/index.js +0 -203
- package/dist/globals/index.d.ts +0 -268
- package/dist/globals/index.js +0 -447
- package/dist/i18n/currency.d.ts +0 -27
- package/dist/i18n/currency.js +0 -100
- package/dist/i18n/date/index.d.ts +0 -210
- package/dist/i18n/date/index.js +0 -552
- package/dist/i18n/date/utils.d.ts +0 -64
- package/dist/i18n/date/utils.js +0 -192
- package/dist/i18n/duration.d.ts +0 -113
- package/dist/i18n/duration.js +0 -398
- package/dist/i18n/format.d.ts +0 -34
- package/dist/i18n/format.js +0 -378
- package/dist/i18n/index.d.ts +0 -9
- package/dist/i18n/index.js +0 -8
- package/dist/itertools/index.d.ts +0 -251
- package/dist/itertools/index.js +0 -434
- package/dist/math/index.d.ts +0 -79
- package/dist/math/index.js +0 -81
- package/dist/mod.d.ts +0 -1
- package/dist/mod.js +0 -1
- package/dist/operators/index.d.ts +0 -148
- package/dist/operators/index.js +0 -325
- package/dist/types.d.ts +0 -19
- package/dist/types.js +0 -1
package/dist/decimal/index.d.ts
CHANGED
|
@@ -1,151 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Exact decimal arithmetic shaped after the TC39 Decimal draft, with Currency.
|
|
3
3
|
*
|
|
4
|
-
* @
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
*
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
* `Decimal` provides support for correct rounded floating point arithmetic, unlike the standard
|
|
12
|
-
* `Number` type. It also supports user-defined precision (default is 20 decimal places), which
|
|
13
|
-
* can be as large as needed.
|
|
4
|
+
* @example
|
|
5
|
+
* ```ts
|
|
6
|
+
* import { Decimal } from 'atomic-fns/decimal'
|
|
7
|
+
*
|
|
8
|
+
* new Decimal('0.1').add('0.2').toString() // '0.3'
|
|
9
|
+
* ```
|
|
10
|
+
* @module
|
|
14
11
|
*/
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
private e;
|
|
19
|
-
/**
|
|
20
|
-
* Returns a new `Decimal` instance from the value or `0`.
|
|
21
|
-
* @param {*} value
|
|
22
|
-
* @returns {Decimal}
|
|
23
|
-
* @throws {ValueError} if the value is not numeric.
|
|
24
|
-
* @throws {RangeError} if the value is infinite or its exponent is past 10,000.
|
|
25
|
-
*/
|
|
26
|
-
constructor(value?: any);
|
|
27
|
-
/**
|
|
28
|
-
* Returns a new `Decimal` that has the opposite sign of this `Decimal`.
|
|
29
|
-
* @example
|
|
30
|
-
```js
|
|
31
|
-
let a = decimal('5')
|
|
32
|
-
a.negated() // -5
|
|
33
|
-
```
|
|
34
|
-
* @returns {Decimal}
|
|
35
|
-
*/
|
|
36
|
-
negated(): Decimal;
|
|
37
|
-
/**
|
|
38
|
-
* Returns a new `Decimal` that is the sum of this and `x`.
|
|
39
|
-
* @param x
|
|
40
|
-
* @example
|
|
41
|
-
```js
|
|
42
|
-
let a = decimal('50000000000')
|
|
43
|
-
let b = decimal('0.000000005')
|
|
44
|
-
a.add(b) // 50000000000.000000005
|
|
45
|
-
```
|
|
46
|
-
* @returns {Decimal}
|
|
47
|
-
*/
|
|
48
|
-
add(x: any): Decimal;
|
|
49
|
-
/**
|
|
50
|
-
* Returns a new `Decimal` that is the difference between this and `x`.
|
|
51
|
-
* @param x
|
|
52
|
-
* @example
|
|
53
|
-
```js
|
|
54
|
-
let a = decimal('1')
|
|
55
|
-
let b = decimal('0.0000000000000000001')
|
|
56
|
-
a.sub(b) // 0.9999999999999999999
|
|
57
|
-
```
|
|
58
|
-
* @returns {Decimal}
|
|
59
|
-
*/
|
|
60
|
-
sub(x: any): Decimal;
|
|
61
|
-
/**
|
|
62
|
-
* Returns a new `Decimal` that is the product of this and `x`.
|
|
63
|
-
* @param x
|
|
64
|
-
* @example
|
|
65
|
-
```js
|
|
66
|
-
let a = decimal('0.0000000000000000000025')
|
|
67
|
-
let b = decimal('400000000000000000000')
|
|
68
|
-
a.mul(b) // 1
|
|
69
|
-
```
|
|
70
|
-
* @returns {Decimal}
|
|
71
|
-
*/
|
|
72
|
-
mul(x: any): Decimal;
|
|
73
|
-
/**
|
|
74
|
-
* Returns a new `Decimal` that is the quotient of this and `x`
|
|
75
|
-
* @param x
|
|
76
|
-
* @example
|
|
77
|
-
```js
|
|
78
|
-
let a = decimal('1')
|
|
79
|
-
let b = decimal('3')
|
|
80
|
-
a.div(b) // 0.33333333333333333333
|
|
81
|
-
```
|
|
82
|
-
* @returns {Decimal}
|
|
83
|
-
*/
|
|
84
|
-
div(x: Decimal | string | number): Decimal;
|
|
85
|
-
/**
|
|
86
|
-
* Returns the square root of this `Decimal`.
|
|
87
|
-
* @returns {Decimal}
|
|
88
|
-
* @throws {ValueError} if this value is negative.
|
|
89
|
-
*/
|
|
90
|
-
sqrt(): Decimal;
|
|
91
|
-
/** Returns a new copy of this Decimal value. */
|
|
92
|
-
clone(): Decimal;
|
|
93
|
-
/**
|
|
94
|
-
* Remove zeroes in the least-significant digit of this `Decimal`
|
|
95
|
-
*/
|
|
96
|
-
private _normalize;
|
|
97
|
-
/**
|
|
98
|
-
* Truncate this `Decimal` to the configured precision
|
|
99
|
-
*/
|
|
100
|
-
private _truncate;
|
|
101
|
-
/**
|
|
102
|
-
* Returns a string representation of this decimal.
|
|
103
|
-
*/
|
|
104
|
-
toString(): string;
|
|
105
|
-
/**
|
|
106
|
-
* Converts this decimal to the `Number` value
|
|
107
|
-
* @returns {number}
|
|
108
|
-
*/
|
|
109
|
-
toNumber(): number;
|
|
110
|
-
static get precision(): number;
|
|
111
|
-
static set precision(value: number);
|
|
112
|
-
/**
|
|
113
|
-
* Returns `true` if this value is equal to the value of `x`, otherwise `false`.
|
|
114
|
-
* @param {*} x other
|
|
115
|
-
* @returns {boolean}
|
|
116
|
-
*/
|
|
117
|
-
eq(x: any): boolean;
|
|
118
|
-
/**
|
|
119
|
-
* Returns `true` if this value is less than the value of `x`, otherwise `false`.
|
|
120
|
-
* @param {*} x
|
|
121
|
-
* @returns {boolean}
|
|
122
|
-
*/
|
|
123
|
-
lt(x: any): boolean;
|
|
124
|
-
/**
|
|
125
|
-
* Returns a comparison value representing the ordering of this value in respect to `x`.
|
|
126
|
-
* * `-1` if this < x
|
|
127
|
-
* * `1` if this > x
|
|
128
|
-
* * `0` if this == x
|
|
129
|
-
* @param {*} x
|
|
130
|
-
* @returns {number}
|
|
131
|
-
*/
|
|
132
|
-
compare(x: any): 0 | 1 | -1;
|
|
133
|
-
/**
|
|
134
|
-
* Returns `true` if this value is greater than the value of `x`, otherwise `false`.
|
|
135
|
-
* @param {*} x
|
|
136
|
-
* @returns {boolean}
|
|
137
|
-
*/
|
|
138
|
-
gt(x: any): boolean;
|
|
139
|
-
/**
|
|
140
|
-
* Returns `true` if this value is less than or equal to the value of `x`, otherwise `false`.
|
|
141
|
-
* @param {*} x
|
|
142
|
-
* @returns {boolean}
|
|
143
|
-
*/
|
|
144
|
-
lte(x: any): boolean;
|
|
145
|
-
/**
|
|
146
|
-
* Returns `true` if this value is greater than or equal to the value of `x`, otherwise `false`.
|
|
147
|
-
* @param {*} x
|
|
148
|
-
* @returns {boolean}
|
|
149
|
-
*/
|
|
150
|
-
gte(x: any): boolean;
|
|
151
|
-
}
|
|
12
|
+
export { Currency } from './currency.js';
|
|
13
|
+
export { Decimal } from './decimal.js';
|
|
14
|
+
export type { DecimalInput, DivideOptions, RoundingMode } from './decimal.js';
|
package/dist/decimal/index.js
CHANGED
|
@@ -1,413 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Exact decimal arithmetic shaped after the TC39 Decimal draft, with Currency.
|
|
3
3
|
*
|
|
4
|
-
* @
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
* Casts the given value as a {@link Decimal}.
|
|
12
|
-
*/
|
|
13
|
-
export function decimal(x) {
|
|
14
|
-
return new Decimal(x);
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* `Decimal` provides support for correct rounded floating point arithmetic, unlike the standard
|
|
18
|
-
* `Number` type. It also supports user-defined precision (default is 20 decimal places), which
|
|
19
|
-
* can be as large as needed.
|
|
4
|
+
* @example
|
|
5
|
+
* ```ts
|
|
6
|
+
* import { Decimal } from 'atomic-fns/decimal'
|
|
7
|
+
*
|
|
8
|
+
* new Decimal('0.1').add('0.2').toString() // '0.3'
|
|
9
|
+
* ```
|
|
10
|
+
* @module
|
|
20
11
|
*/
|
|
21
|
-
export
|
|
22
|
-
|
|
23
|
-
i = 0n;
|
|
24
|
-
e = 0;
|
|
25
|
-
/**
|
|
26
|
-
* Returns a new `Decimal` instance from the value or `0`.
|
|
27
|
-
* @param {*} value
|
|
28
|
-
* @returns {Decimal}
|
|
29
|
-
* @throws {ValueError} if the value is not numeric.
|
|
30
|
-
* @throws {RangeError} if the value is infinite or its exponent is past 10,000.
|
|
31
|
-
*/
|
|
32
|
-
constructor(value) {
|
|
33
|
-
if (value == null) {
|
|
34
|
-
return this;
|
|
35
|
-
}
|
|
36
|
-
// Check if value is a Decimal like
|
|
37
|
-
if (typeof value?.i === 'bigint' && typeof value.e === 'number') {
|
|
38
|
-
this.i = value.i;
|
|
39
|
-
this.e = value.e;
|
|
40
|
-
this._normalize();
|
|
41
|
-
return this;
|
|
42
|
-
}
|
|
43
|
-
const text = value.toString();
|
|
44
|
-
const result = NUMBER_REGEX.exec(text);
|
|
45
|
-
if (result) {
|
|
46
|
-
// console.log(result);
|
|
47
|
-
// Construct from string if possible
|
|
48
|
-
// this.i = parseInt(result[1] + result[2] + result[4]);
|
|
49
|
-
if (typeof result[2] === 'undefined')
|
|
50
|
-
result[2] = '';
|
|
51
|
-
if (typeof result[4] === 'undefined')
|
|
52
|
-
result[4] = '';
|
|
53
|
-
this.i = BigInt(result[1] + result[2] + result[4]);
|
|
54
|
-
this.e = Number(result[5] ?? 0) - result[4].length;
|
|
55
|
-
this._normalize();
|
|
56
|
-
if (result[5]) {
|
|
57
|
-
const magnitude = this.e + (this.i < 0n ? -this.i : this.i).toString().length - 1;
|
|
58
|
-
if (this.i === 0n)
|
|
59
|
-
this.e = 0;
|
|
60
|
-
else if (Math.abs(magnitude) > MAX_EXPONENT)
|
|
61
|
-
throw new RangeError('exponent out of range');
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
// Conversion to string failed, so construct from number
|
|
66
|
-
value = Number(value);
|
|
67
|
-
if (Number.isNaN(value) || (value === 0 && text.trim() === '')) {
|
|
68
|
-
throw new ValueError('Decimal value must be numeric');
|
|
69
|
-
}
|
|
70
|
-
let m = 1n;
|
|
71
|
-
if (value < 0) {
|
|
72
|
-
value = -value;
|
|
73
|
-
m = -1n;
|
|
74
|
-
}
|
|
75
|
-
if (value === 0) {
|
|
76
|
-
this.i = 0n;
|
|
77
|
-
this.e = 0;
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
// Multiply the number by 10 until it is an integer
|
|
81
|
-
let e = -Math.floor(Math.log10(value));
|
|
82
|
-
if (e > 0) {
|
|
83
|
-
value *= 10 ** e;
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
e = 0;
|
|
87
|
-
}
|
|
88
|
-
while (value !== Math.round(value)) {
|
|
89
|
-
e++;
|
|
90
|
-
value *= 10;
|
|
91
|
-
}
|
|
92
|
-
// Divide the number by 10 until the one's digit is non-zero
|
|
93
|
-
while (value % 10 === 0 && value > 0) {
|
|
94
|
-
e--;
|
|
95
|
-
value /= 10;
|
|
96
|
-
}
|
|
97
|
-
value = BigInt(value);
|
|
98
|
-
this.i = value * m;
|
|
99
|
-
this.e = -e;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Returns a new `Decimal` that has the opposite sign of this `Decimal`.
|
|
105
|
-
* @example
|
|
106
|
-
```js
|
|
107
|
-
let a = decimal('5')
|
|
108
|
-
a.negated() // -5
|
|
109
|
-
```
|
|
110
|
-
* @returns {Decimal}
|
|
111
|
-
*/
|
|
112
|
-
negated() {
|
|
113
|
-
const negated = new Decimal();
|
|
114
|
-
negated.i = -this.i;
|
|
115
|
-
negated.e = this.e;
|
|
116
|
-
return negated;
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Returns a new `Decimal` that is the sum of this and `x`.
|
|
120
|
-
* @param x
|
|
121
|
-
* @example
|
|
122
|
-
```js
|
|
123
|
-
let a = decimal('50000000000')
|
|
124
|
-
let b = decimal('0.000000005')
|
|
125
|
-
a.add(b) // 50000000000.000000005
|
|
126
|
-
```
|
|
127
|
-
* @returns {Decimal}
|
|
128
|
-
*/
|
|
129
|
-
add(x) {
|
|
130
|
-
let a = new Decimal(this);
|
|
131
|
-
let b = new Decimal(x);
|
|
132
|
-
// a+b = a.i * 10^a.e + b.i * 10^b.e
|
|
133
|
-
// a+b = ( a.i * 10^(a.e-b.e) + b.i ) * 10^b.e
|
|
134
|
-
const result = new Decimal();
|
|
135
|
-
// Order arguments so that a.e >= b.e
|
|
136
|
-
if (a.e < b.e) {
|
|
137
|
-
const c = a;
|
|
138
|
-
a = b;
|
|
139
|
-
b = c;
|
|
140
|
-
}
|
|
141
|
-
const intPart = exp(a.i, a.e - b.e);
|
|
142
|
-
result.i = intPart + b.i;
|
|
143
|
-
result.e = b.e;
|
|
144
|
-
result._normalize();
|
|
145
|
-
return result;
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Returns a new `Decimal` that is the difference between this and `x`.
|
|
149
|
-
* @param x
|
|
150
|
-
* @example
|
|
151
|
-
```js
|
|
152
|
-
let a = decimal('1')
|
|
153
|
-
let b = decimal('0.0000000000000000001')
|
|
154
|
-
a.sub(b) // 0.9999999999999999999
|
|
155
|
-
```
|
|
156
|
-
* @returns {Decimal}
|
|
157
|
-
*/
|
|
158
|
-
sub(x) {
|
|
159
|
-
return this.add(decimal(x).negated());
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Returns a new `Decimal` that is the product of this and `x`.
|
|
163
|
-
* @param x
|
|
164
|
-
* @example
|
|
165
|
-
```js
|
|
166
|
-
let a = decimal('0.0000000000000000000025')
|
|
167
|
-
let b = decimal('400000000000000000000')
|
|
168
|
-
a.mul(b) // 1
|
|
169
|
-
```
|
|
170
|
-
* @returns {Decimal}
|
|
171
|
-
*/
|
|
172
|
-
mul(x) {
|
|
173
|
-
const a = new Decimal(this);
|
|
174
|
-
const b = new Decimal(x);
|
|
175
|
-
// a * b = (a.i * b.i) * 10^(a.e + b.e)
|
|
176
|
-
const result = new Decimal();
|
|
177
|
-
result.i = a.i * b.i;
|
|
178
|
-
result.e = a.e + b.e;
|
|
179
|
-
result._normalize();
|
|
180
|
-
return result;
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Returns a new `Decimal` that is the quotient of this and `x`
|
|
184
|
-
* @param x
|
|
185
|
-
* @example
|
|
186
|
-
```js
|
|
187
|
-
let a = decimal('1')
|
|
188
|
-
let b = decimal('3')
|
|
189
|
-
a.div(b) // 0.33333333333333333333
|
|
190
|
-
```
|
|
191
|
-
* @returns {Decimal}
|
|
192
|
-
*/
|
|
193
|
-
div(x) {
|
|
194
|
-
const a = new Decimal(this);
|
|
195
|
-
const b = new Decimal(x);
|
|
196
|
-
// We need to increase the number of digits of a and b so that a / b will have the desired precision.
|
|
197
|
-
// In order for the integer quotient to have the correct precision, a.e - b.e must be greater than that precision.
|
|
198
|
-
// So we need only to increase a.e.
|
|
199
|
-
// The quotient needs precision + a.e - b.e, and a negative a.e keeps the digits it always had
|
|
200
|
-
const increaseA = Math.max(Decimal.precision + Math.abs(a.e) - b.e, 0);
|
|
201
|
-
const intIncrease = new Decimal();
|
|
202
|
-
intIncrease.i = exp(a.i, increaseA);
|
|
203
|
-
const quotient = new Decimal();
|
|
204
|
-
quotient.i = intIncrease.i / b.i;
|
|
205
|
-
quotient.e = a.e - b.e - increaseA;
|
|
206
|
-
// No need to truncate since we already increased the number of digits before dividing
|
|
207
|
-
quotient._normalize();
|
|
208
|
-
return quotient;
|
|
209
|
-
}
|
|
210
|
-
/**
|
|
211
|
-
* Returns the square root of this `Decimal`.
|
|
212
|
-
* @returns {Decimal}
|
|
213
|
-
* @throws {ValueError} if this value is negative.
|
|
214
|
-
*/
|
|
215
|
-
sqrt() {
|
|
216
|
-
if (this.i < 0n)
|
|
217
|
-
throw new ValueError('square root of a negative number');
|
|
218
|
-
Decimal.PRECISION++;
|
|
219
|
-
// Let the guess value be 10^(m/2), where m is the magnitude of this value
|
|
220
|
-
let x = new Decimal();
|
|
221
|
-
x.i = 1n;
|
|
222
|
-
x.e = Math.floor((this.e + this.i.toString().length) / 2);
|
|
223
|
-
const onehalf = new Decimal('0.5');
|
|
224
|
-
let xt = x.clone();
|
|
225
|
-
xt._truncate();
|
|
226
|
-
xt._normalize();
|
|
227
|
-
let lastxt;
|
|
228
|
-
let i;
|
|
229
|
-
for (i = 0; i < 100; i++) {
|
|
230
|
-
lastxt = xt;
|
|
231
|
-
x = this.div(x).add(x).mul(onehalf);
|
|
232
|
-
xt = x.clone();
|
|
233
|
-
xt._truncate();
|
|
234
|
-
xt._normalize();
|
|
235
|
-
if (xt.i === lastxt.i && xt.e === lastxt.e)
|
|
236
|
-
break;
|
|
237
|
-
}
|
|
238
|
-
if (i >= 100) {
|
|
239
|
-
console.log('Warning: sqrt exceeded maximum iterations. (Did it enter a cycle?)');
|
|
240
|
-
}
|
|
241
|
-
Decimal.PRECISION--;
|
|
242
|
-
xt._truncate();
|
|
243
|
-
xt._normalize();
|
|
244
|
-
// Rounding twice can leave the last digit one too high, so check it against the exact square
|
|
245
|
-
const half = new Decimal();
|
|
246
|
-
half.i = 5n;
|
|
247
|
-
half.e = -Decimal.PRECISION - 1;
|
|
248
|
-
const low = xt.sub(half);
|
|
249
|
-
if (low.gt(0) && low.mul(low).gt(this))
|
|
250
|
-
return low.sub(half);
|
|
251
|
-
return xt;
|
|
252
|
-
}
|
|
253
|
-
/** Returns a new copy of this Decimal value. */
|
|
254
|
-
clone() {
|
|
255
|
-
const a = new Decimal();
|
|
256
|
-
a.i = this.i;
|
|
257
|
-
a.e = this.e;
|
|
258
|
-
return a;
|
|
259
|
-
}
|
|
260
|
-
/**
|
|
261
|
-
* Remove zeroes in the least-significant digit of this `Decimal`
|
|
262
|
-
*/
|
|
263
|
-
_normalize() {
|
|
264
|
-
if (this.i === 0n)
|
|
265
|
-
this.e = Math.min(this.e, 0);
|
|
266
|
-
if (this.i === 0n || this.i % 10n !== 0n)
|
|
267
|
-
return this;
|
|
268
|
-
const digits = this.i.toString();
|
|
269
|
-
let end = digits.length;
|
|
270
|
-
while (digits[end - 1] === '0')
|
|
271
|
-
end--;
|
|
272
|
-
this.i = BigInt(digits.slice(0, end));
|
|
273
|
-
this.e += digits.length - end;
|
|
274
|
-
return this;
|
|
275
|
-
}
|
|
276
|
-
/**
|
|
277
|
-
* Truncate this `Decimal` to the configured precision
|
|
278
|
-
*/
|
|
279
|
-
_truncate() {
|
|
280
|
-
// TODO: Make this better
|
|
281
|
-
// TODO: Rounding
|
|
282
|
-
const trunc = -this.e - Decimal.PRECISION;
|
|
283
|
-
if (trunc > 0) {
|
|
284
|
-
this.i /= 10n ** BigInt(trunc - 1);
|
|
285
|
-
this.e += trunc;
|
|
286
|
-
const nextDigit = this.i % 10n;
|
|
287
|
-
if (nextDigit >= 5) {
|
|
288
|
-
this.i += 10n;
|
|
289
|
-
}
|
|
290
|
-
this.i /= 10n;
|
|
291
|
-
}
|
|
292
|
-
// while(-this.e > Decimal.PRECISION) {
|
|
293
|
-
// this.i /= 10n;
|
|
294
|
-
// this.e++;
|
|
295
|
-
// }
|
|
296
|
-
return this;
|
|
297
|
-
}
|
|
298
|
-
/**
|
|
299
|
-
* Returns a string representation of this decimal.
|
|
300
|
-
*/
|
|
301
|
-
toString() {
|
|
302
|
-
let s = this.i.toString();
|
|
303
|
-
let m = '';
|
|
304
|
-
if (s[0] === '-') {
|
|
305
|
-
s = s.substring(1, s.length);
|
|
306
|
-
m = '-';
|
|
307
|
-
}
|
|
308
|
-
if (this.e > 0) {
|
|
309
|
-
return m + s + '0'.repeat(this.e);
|
|
310
|
-
}
|
|
311
|
-
else if (this.e < 0) {
|
|
312
|
-
if (-this.e >= s.length) {
|
|
313
|
-
return `${m}0.${'0'.repeat(-this.e - s.length)}${s}`;
|
|
314
|
-
}
|
|
315
|
-
return `${m}${s.slice(0, s.length + this.e)}.${s.slice(s.length + this.e, s.length)}`;
|
|
316
|
-
}
|
|
317
|
-
else {
|
|
318
|
-
return m + s;
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
322
|
-
return this.toString();
|
|
323
|
-
}
|
|
324
|
-
/**
|
|
325
|
-
* Converts this decimal to the `Number` value
|
|
326
|
-
* @returns {number}
|
|
327
|
-
*/
|
|
328
|
-
toNumber() {
|
|
329
|
-
return Number(Decimal.prototype.toString.call(this));
|
|
330
|
-
}
|
|
331
|
-
static get precision() {
|
|
332
|
-
return Decimal.PRECISION;
|
|
333
|
-
}
|
|
334
|
-
static set precision(value) {
|
|
335
|
-
Decimal.PRECISION = value;
|
|
336
|
-
}
|
|
337
|
-
/**
|
|
338
|
-
* Returns `true` if this value is equal to the value of `x`, otherwise `false`.
|
|
339
|
-
* @param {*} x other
|
|
340
|
-
* @returns {boolean}
|
|
341
|
-
*/
|
|
342
|
-
eq(x) {
|
|
343
|
-
if (x == null || typeof x === 'boolean')
|
|
344
|
-
return false;
|
|
345
|
-
let other;
|
|
346
|
-
try {
|
|
347
|
-
other = decimal(x);
|
|
348
|
-
}
|
|
349
|
-
catch {
|
|
350
|
-
return false;
|
|
351
|
-
}
|
|
352
|
-
return this.i === other.i && (this.e === other.e || this.i === 0n);
|
|
353
|
-
}
|
|
354
|
-
/**
|
|
355
|
-
* Returns `true` if this value is less than the value of `x`, otherwise `false`.
|
|
356
|
-
* @param {*} x
|
|
357
|
-
* @returns {boolean}
|
|
358
|
-
*/
|
|
359
|
-
lt(x) {
|
|
360
|
-
const other = decimal(x);
|
|
361
|
-
if (this.e === other.e)
|
|
362
|
-
return this.i < other.i;
|
|
363
|
-
const e = this.e - other.e;
|
|
364
|
-
if (e > 0) {
|
|
365
|
-
return exp(this.i, e) < other.i;
|
|
366
|
-
}
|
|
367
|
-
return this.i < exp(other.i, -e);
|
|
368
|
-
}
|
|
369
|
-
/**
|
|
370
|
-
* Returns a comparison value representing the ordering of this value in respect to `x`.
|
|
371
|
-
* * `-1` if this < x
|
|
372
|
-
* * `1` if this > x
|
|
373
|
-
* * `0` if this == x
|
|
374
|
-
* @param {*} x
|
|
375
|
-
* @returns {number}
|
|
376
|
-
*/
|
|
377
|
-
compare(x) {
|
|
378
|
-
const other = x == null || typeof x === 'boolean' ? decimal(x) : x;
|
|
379
|
-
if (this.eq(other))
|
|
380
|
-
return 0;
|
|
381
|
-
if (this.lt(other))
|
|
382
|
-
return -1;
|
|
383
|
-
return 1;
|
|
384
|
-
}
|
|
385
|
-
/**
|
|
386
|
-
* Returns `true` if this value is greater than the value of `x`, otherwise `false`.
|
|
387
|
-
* @param {*} x
|
|
388
|
-
* @returns {boolean}
|
|
389
|
-
*/
|
|
390
|
-
gt(x) {
|
|
391
|
-
return this.compare(x) > 0;
|
|
392
|
-
}
|
|
393
|
-
/**
|
|
394
|
-
* Returns `true` if this value is less than or equal to the value of `x`, otherwise `false`.
|
|
395
|
-
* @param {*} x
|
|
396
|
-
* @returns {boolean}
|
|
397
|
-
*/
|
|
398
|
-
lte(x) {
|
|
399
|
-
return this.compare(x) <= 0;
|
|
400
|
-
}
|
|
401
|
-
/**
|
|
402
|
-
* Returns `true` if this value is greater than or equal to the value of `x`, otherwise `false`.
|
|
403
|
-
* @param {*} x
|
|
404
|
-
* @returns {boolean}
|
|
405
|
-
*/
|
|
406
|
-
gte(x) {
|
|
407
|
-
return this.compare(x) >= 0;
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
/** Returns a BigInt that is equal to `i` times `10^e` */
|
|
411
|
-
function exp(i, e) {
|
|
412
|
-
return i * 10n ** BigInt(e);
|
|
413
|
-
}
|
|
12
|
+
export { Currency } from './currency.js';
|
|
13
|
+
export { Decimal } from './decimal.js';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** UTF-16 units of bad input an error message repeats. */
|
|
2
|
+
export const MAX_ECHO = 40;
|
|
3
|
+
/** `value` quoted and cut to {@link MAX_ECHO} units. */
|
|
4
|
+
export function quoteForError(value) {
|
|
5
|
+
return `${JSON.stringify(value.slice(0, MAX_ECHO))}${value.length > MAX_ECHO ? '...' : ''}`;
|
|
6
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Floor integer square root via precision doubling.
|
|
3
|
+
* Below 2^52 uses `Math.sqrt` with an exact fix-up; larger n recurse on
|
|
4
|
+
* `n >> 2k` then one Newton step and one +-1 correction.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isqrtRoot(n: bigint): {
|
|
7
|
+
root: bigint;
|
|
8
|
+
exact: boolean;
|
|
9
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { bitLength } from './bits.js';
|
|
2
|
+
/**
|
|
3
|
+
* Adjust `x` so `x*x <= n < (x+1)*(x+1)` (one +-1 step).
|
|
4
|
+
* Returns the root and whether `x*x === n` (avoids a second full square in callers).
|
|
5
|
+
*/
|
|
6
|
+
function isqrtFix(x, n) {
|
|
7
|
+
let y = x;
|
|
8
|
+
let y2 = y * y;
|
|
9
|
+
// Newton / Math.sqrt estimate is within 1 of the true floor root.
|
|
10
|
+
if (y2 > n) {
|
|
11
|
+
y--;
|
|
12
|
+
y2 = y * y;
|
|
13
|
+
}
|
|
14
|
+
else if (y2 + ((y << 1n) + 1n) <= n) {
|
|
15
|
+
y++;
|
|
16
|
+
y2 = y * y;
|
|
17
|
+
}
|
|
18
|
+
return { root: y, exact: y2 === n };
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Floor integer square root via precision doubling.
|
|
22
|
+
* Below 2^52 uses `Math.sqrt` with an exact fix-up; larger n recurse on
|
|
23
|
+
* `n >> 2k` then one Newton step and one +-1 correction.
|
|
24
|
+
*/
|
|
25
|
+
export function isqrtRoot(n) {
|
|
26
|
+
if (n <= 1n)
|
|
27
|
+
return { root: n, exact: true };
|
|
28
|
+
if (n < 1n << 52n) {
|
|
29
|
+
return isqrtFix(BigInt(Math.floor(Math.sqrt(Number(n)))), n);
|
|
30
|
+
}
|
|
31
|
+
const k = Math.floor(bitLength(n) / 4);
|
|
32
|
+
const r = isqrtRoot(n >> BigInt(2 * k)).root << BigInt(k);
|
|
33
|
+
return isqrtFix((r + n / r) >> 1n, n);
|
|
34
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical tags for `locales`; an empty list means the runtime's locale.
|
|
3
|
+
* @throws {TypeError} for an entry that is neither a string nor an `Intl.Locale`.
|
|
4
|
+
* @throws {RangeError} for a list longer than 255 characters, which the engine canonicalizes in
|
|
5
|
+
* quadratic time, or a malformed tag.
|
|
6
|
+
*/
|
|
7
|
+
export declare function canonicalLocales(locales: Intl.LocalesArgument): string[];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Longest locale list, joined, that `Intl` is asked to canonicalize. */
|
|
2
|
+
const MAX_LOCALE_LENGTH = 255;
|
|
3
|
+
/**
|
|
4
|
+
* Canonical tags for `locales`; an empty list means the runtime's locale.
|
|
5
|
+
* @throws {TypeError} for an entry that is neither a string nor an `Intl.Locale`.
|
|
6
|
+
* @throws {RangeError} for a list longer than 255 characters, which the engine canonicalizes in
|
|
7
|
+
* quadratic time, or a malformed tag.
|
|
8
|
+
*/
|
|
9
|
+
export function canonicalLocales(locales) {
|
|
10
|
+
if (locales === undefined)
|
|
11
|
+
return [];
|
|
12
|
+
const entries = Array.isArray(locales) ? locales : [locales];
|
|
13
|
+
const tags = entries.map((entry) => {
|
|
14
|
+
if (typeof entry === 'string')
|
|
15
|
+
return entry;
|
|
16
|
+
if (entry instanceof Intl.Locale)
|
|
17
|
+
return entry.toString();
|
|
18
|
+
throw new TypeError('locale must be a string or an Intl.Locale');
|
|
19
|
+
});
|
|
20
|
+
if (tags.join().length > MAX_LOCALE_LENGTH) {
|
|
21
|
+
throw new RangeError(`locale is longer than ${String(MAX_LOCALE_LENGTH)} characters`);
|
|
22
|
+
}
|
|
23
|
+
return Intl.getCanonicalLocales(tags);
|
|
24
|
+
}
|