arbitrary-numbers 1.0.2 → 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 +480 -375
- package/dist/index.cjs +970 -696
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +441 -505
- package/dist/index.d.ts +441 -505
- package/dist/index.js +969 -693
- package/dist/index.js.map +1 -1
- package/package.json +9 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,17 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A number stored in normalised scientific notation as `coefficient * 10^exponent`,
|
|
3
|
-
* where `1 <= |coefficient| < 10` (or `coefficient === 0`).
|
|
4
|
-
*
|
|
5
|
-
* @example
|
|
6
|
-
* const n: NormalizedNumber = { coefficient: 1.5, exponent: 3 }; // 1500
|
|
7
|
-
* const z: NormalizedNumber = { coefficient: 0, exponent: 0 }; // 0
|
|
8
|
-
*/
|
|
9
|
-
interface NormalizedNumber {
|
|
10
|
-
/** The significand, always in `[1, 10)` or `0`. */
|
|
11
|
-
coefficient: number;
|
|
12
|
-
/** The power of 10 by which the coefficient is scaled. */
|
|
13
|
-
exponent: number;
|
|
14
|
-
}
|
|
15
1
|
/** The result of a three-way comparison: negative, zero, or positive. */
|
|
16
2
|
type Signum = -1 | 0 | 1;
|
|
17
3
|
/** Remainder after dividing an exponent by 3 - the within-tier offset. */
|
|
@@ -27,6 +13,44 @@ interface AnFunction {
|
|
|
27
13
|
from(value: number): ArbitraryNumber;
|
|
28
14
|
}
|
|
29
15
|
|
|
16
|
+
/**
|
|
17
|
+
* A value that can be either a plain `number` or an `ArbitraryNumber`.
|
|
18
|
+
*/
|
|
19
|
+
type ArbitraryNumberish = ArbitraryNumber | number;
|
|
20
|
+
/**
|
|
21
|
+
* A value that is either `T` or `undefined`.
|
|
22
|
+
*
|
|
23
|
+
* Use for genuinely optional values where the absence is meaningful
|
|
24
|
+
* (e.g. optional names, optional fallback plugins).
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* let label: Maybe<string>; // string | undefined
|
|
28
|
+
*/
|
|
29
|
+
type Maybe<T> = T | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* A value that is either `T` or `null`.
|
|
32
|
+
*
|
|
33
|
+
* Use for explicit "no result" returns from functions that would otherwise throw
|
|
34
|
+
* (e.g. `tryFrom` at system boundaries where bad input should be handled gracefully).
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* function parse(s: string): Nullable<ArbitraryNumber> { ... }
|
|
38
|
+
*/
|
|
39
|
+
type Nullable<T> = T | null;
|
|
40
|
+
/**
|
|
41
|
+
* A stable, compact JSON representation of an {@link ArbitraryNumber}.
|
|
42
|
+
*
|
|
43
|
+
* Keys are intentionally short (`c`/`e`) to keep save-game blobs small.
|
|
44
|
+
* Produced by {@link ArbitraryNumber.toJSON} and consumed by {@link ArbitraryNumber.fromJSON}.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* const saved: ArbitraryNumberJson = an(1500).toJSON(); // { c: 1.5, e: 3 }
|
|
48
|
+
*/
|
|
49
|
+
type ArbitraryNumberJson = {
|
|
50
|
+
c: number;
|
|
51
|
+
e: number;
|
|
52
|
+
};
|
|
53
|
+
|
|
30
54
|
/**
|
|
31
55
|
* A plugin that formats a normalised scientific notation number into a display string.
|
|
32
56
|
*
|
|
@@ -91,7 +115,7 @@ interface SuffixNotationPluginOptions {
|
|
|
91
115
|
*
|
|
92
116
|
* @example " " -> "1.50 K" | "" -> "1.50K"
|
|
93
117
|
*/
|
|
94
|
-
separator?: string
|
|
118
|
+
separator?: Maybe<string>;
|
|
95
119
|
}
|
|
96
120
|
/**
|
|
97
121
|
* A display label for one tier of magnitude, used by {@link UnitNotation}.
|
|
@@ -108,7 +132,7 @@ interface Unit {
|
|
|
108
132
|
/** Short symbol displayed after the number, e.g. `"M"`. */
|
|
109
133
|
symbol: string;
|
|
110
134
|
/** Optional full name, e.g. `"Million"`. Used for display purposes only. */
|
|
111
|
-
name?: string
|
|
135
|
+
name?: Maybe<string>;
|
|
112
136
|
}
|
|
113
137
|
/**
|
|
114
138
|
* A tier-indexed array of units for use with {@link UnitNotation}.
|
|
@@ -126,7 +150,7 @@ interface Unit {
|
|
|
126
150
|
* { symbol: "M" }, // tier 2: millions
|
|
127
151
|
* ];
|
|
128
152
|
*/
|
|
129
|
-
type UnitArray = ReadonlyArray<Unit
|
|
153
|
+
type UnitArray = ReadonlyArray<Maybe<Unit>>;
|
|
130
154
|
/**
|
|
131
155
|
* Options for constructing an {@link AlphabetNotation} instance.
|
|
132
156
|
*/
|
|
@@ -140,7 +164,7 @@ interface AlphabetNotationOptions extends SuffixNotationPluginOptions {
|
|
|
140
164
|
*
|
|
141
165
|
* @default `"abcdefghijklmnopqrstuvwxyz"`
|
|
142
166
|
*/
|
|
143
|
-
alphabet?: string
|
|
167
|
+
alphabet?: Maybe<string>;
|
|
144
168
|
}
|
|
145
169
|
/**
|
|
146
170
|
* Options for constructing a {@link UnitNotation} instance.
|
|
@@ -168,234 +192,354 @@ interface UnitNotationOptions extends SuffixNotationPluginOptions {
|
|
|
168
192
|
*
|
|
169
193
|
* @default undefined
|
|
170
194
|
*/
|
|
171
|
-
fallback?: SuffixProvider
|
|
195
|
+
fallback?: Maybe<SuffixProvider>;
|
|
196
|
+
/**
|
|
197
|
+
* When `true` (default), the fallback's tier is offset by the last defined tier in `units`
|
|
198
|
+
* so that fallback suffixes are visually distinct from those the fallback would generate
|
|
199
|
+
* for low tiers.
|
|
200
|
+
*
|
|
201
|
+
* Example with `CLASSIC_UNITS` (last defined tier = 33) and `letterNotation` as fallback:
|
|
202
|
+
* - `offsetFallback: true` → exponent 102 (tier 34) → `"a"` (fallback tier 1, distinct from "K")
|
|
203
|
+
* - `offsetFallback: false` → exponent 102 (tier 34) → `"h"` (fallback tier 34, same as exponent 24)
|
|
204
|
+
*
|
|
205
|
+
* Set to `false` only for backwards compatibility with pre-1.1 behaviour.
|
|
206
|
+
*
|
|
207
|
+
* @default true
|
|
208
|
+
*/
|
|
209
|
+
offsetFallback?: Maybe<boolean>;
|
|
172
210
|
}
|
|
173
211
|
|
|
174
212
|
/**
|
|
175
|
-
*
|
|
213
|
+
* Global tunables for `ArbitraryNumber`.
|
|
214
|
+
*
|
|
215
|
+
* Mutating these is a process-level change — not per-instance.
|
|
216
|
+
*/
|
|
217
|
+
interface ArbitraryNumberDefaults {
|
|
218
|
+
/**
|
|
219
|
+
* Exponent-difference threshold below which the smaller operand is negligible
|
|
220
|
+
* and silently skipped during addition/subtraction.
|
|
221
|
+
*
|
|
222
|
+
* Default: 15 (matches float64 coefficient precision of ~15.95 significant digits).
|
|
223
|
+
*/
|
|
224
|
+
scaleCutoff: number;
|
|
225
|
+
/** Default decimal places used by `toString()` when no argument is supplied. */
|
|
226
|
+
notationDecimals: number;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* A mutable number with effectively unlimited range, stored as `coefficient * 10^exponent`
|
|
176
230
|
* in normalised scientific notation.
|
|
177
231
|
*
|
|
178
|
-
* The coefficient is always in `[1, 10)` (or `0`).
|
|
179
|
-
*
|
|
180
|
-
*
|
|
232
|
+
* The coefficient is always in `[1, 10)` (or `0`). Arithmetic methods **mutate `this`** and
|
|
233
|
+
* return `this` — enabling zero-allocation chaining on the hot path:
|
|
234
|
+
*
|
|
235
|
+
* ```ts
|
|
236
|
+
* gold.add(drop).sub(cost).mul(multiplier);
|
|
237
|
+
* ```
|
|
238
|
+
*
|
|
239
|
+
* Call `.clone()` before any operation where you need to preserve the original value.
|
|
240
|
+
*
|
|
241
|
+
* Addition short-circuits when the exponent difference between operands exceeds
|
|
242
|
+
* {@link ArbitraryNumber.defaults.scaleCutoff} — the smaller value is below the precision
|
|
243
|
+
* floor and is silently discarded.
|
|
244
|
+
*
|
|
245
|
+
* **Static = allocate. Instance = mutate.**
|
|
246
|
+
* Static arithmetic methods (`ArbitraryNumber.add`, etc.) always return a new instance.
|
|
247
|
+
* Instance methods (`a.add(b)`) mutate `a` and return `a`.
|
|
181
248
|
*
|
|
182
249
|
* @example
|
|
183
|
-
* const
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
* a.mul(b).toString(); // "3.75e+6"
|
|
250
|
+
* const gold = new ArbitraryNumber(1.5, 3); // 1_500
|
|
251
|
+
* gold.add(drop).sub(cost).mul(multiplier); // mutates gold
|
|
252
|
+
* const snapshot = gold.clone(); // safe copy
|
|
187
253
|
*/
|
|
188
|
-
declare class ArbitraryNumber
|
|
254
|
+
declare class ArbitraryNumber {
|
|
189
255
|
/** The significand, always in `[1, 10)` or `0`. */
|
|
190
|
-
|
|
256
|
+
coefficient: number;
|
|
191
257
|
/** The power of 10 by which the coefficient is scaled. */
|
|
192
|
-
|
|
258
|
+
exponent: number;
|
|
259
|
+
/** Global tunables. Mutating these is a process-level change. */
|
|
260
|
+
static readonly defaults: ArbitraryNumberDefaults;
|
|
261
|
+
/** The additive identity: `0`. Frozen — calling mutating methods throws. */
|
|
262
|
+
static readonly Zero: FrozenArbitraryNumber;
|
|
263
|
+
/** The multiplicative identity: `1`. Frozen — calling mutating methods throws. */
|
|
264
|
+
static readonly One: FrozenArbitraryNumber;
|
|
265
|
+
/** `10`. Frozen — calling mutating methods throws. */
|
|
266
|
+
static readonly Ten: FrozenArbitraryNumber;
|
|
193
267
|
/**
|
|
194
|
-
*
|
|
195
|
-
*
|
|
268
|
+
* Constructs a new `ArbitraryNumber` and immediately normalises it so that
|
|
269
|
+
* `1 <= |coefficient| < 10` (or `coefficient === 0`).
|
|
196
270
|
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
271
|
+
* Always two numeric arguments — this keeps the constructor monomorphic so V8
|
|
272
|
+
* locks in a hidden class on first use (~5 ns allocation).
|
|
199
273
|
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
274
|
+
* @example
|
|
275
|
+
* new ArbitraryNumber(15, 3); // stored as { coefficient: 1.5, exponent: 4 }
|
|
202
276
|
*
|
|
203
|
-
*
|
|
277
|
+
* @throws `ArbitraryNumberInputError` for `NaN`/`Infinity` coefficient or exponent.
|
|
204
278
|
*/
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
279
|
+
constructor(coefficient: number, exponent: number);
|
|
280
|
+
/**
|
|
281
|
+
* @internal Fast-path factory for already-normalised values. Not exported from `index.ts`.
|
|
282
|
+
*
|
|
283
|
+
* Allocates a new instance and writes the two fields directly — bypasses validation
|
|
284
|
+
* and normalisation. Only valid when `|coefficient|` is already in `[1, 10)` (or 0)
|
|
285
|
+
* and `exponent` is correct.
|
|
286
|
+
*/
|
|
287
|
+
static unsafe(coefficient: number, exponent: number): ArbitraryNumber;
|
|
288
|
+
/** @internal Normalise an arbitrary `(c, e)` pair into a new instance. */
|
|
289
|
+
private static _normalizeNew;
|
|
290
|
+
/** @internal Normalise `(c, e)` into `this` (mutates). Returns `this`. */
|
|
291
|
+
private _normalizeInto;
|
|
292
|
+
/**
|
|
293
|
+
* Returns a fresh, unfrozen copy of this number. The canonical way to preserve
|
|
294
|
+
* a value before mutating it:
|
|
295
|
+
*
|
|
296
|
+
* ```ts
|
|
297
|
+
* const before = gold.clone();
|
|
298
|
+
* gold.add(drop);
|
|
299
|
+
* ```
|
|
300
|
+
*/
|
|
301
|
+
clone(): ArbitraryNumber;
|
|
212
302
|
/**
|
|
213
303
|
* Creates an `ArbitraryNumber` from a plain JavaScript `number`.
|
|
214
304
|
*
|
|
215
|
-
*
|
|
216
|
-
* ordinary numeric literals - it reads clearly at the call site and
|
|
217
|
-
* validates the input.
|
|
305
|
+
* @throws `ArbitraryNumberInputError` for `NaN`, `Infinity`, or `-Infinity`.
|
|
218
306
|
*
|
|
219
307
|
* @example
|
|
220
|
-
* ArbitraryNumber.from(1500);
|
|
221
|
-
* ArbitraryNumber.from(0.005); // { coefficient: 5, exponent: -3 }
|
|
222
|
-
* ArbitraryNumber.from(0); // ArbitraryNumber.Zero
|
|
223
|
-
*
|
|
224
|
-
* @param value - Any finite number.
|
|
225
|
-
* @throws `"ArbitraryNumber.from: value must be finite"` for `NaN`, `Infinity`, or `-Infinity`.
|
|
308
|
+
* ArbitraryNumber.from(1500); // { coefficient: 1.5, exponent: 3 }
|
|
226
309
|
*/
|
|
227
310
|
static from(value: number): ArbitraryNumber;
|
|
228
311
|
/**
|
|
229
|
-
*
|
|
230
|
-
* `1 <= |coefficient| < 10` (or `coefficient === 0`).
|
|
312
|
+
* Like `from`, but returns `null` instead of throwing for non-finite inputs.
|
|
231
313
|
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
314
|
+
* Use at system boundaries (form inputs, external APIs) where bad input should
|
|
315
|
+
* be handled gracefully.
|
|
234
316
|
*
|
|
235
|
-
* @
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
* @throws `"ArbitraryNumber: exponent must be finite"` for non-finite exponents.
|
|
317
|
+
* @example
|
|
318
|
+
* ArbitraryNumber.tryFrom(Infinity) // null
|
|
319
|
+
* ArbitraryNumber.tryFrom(1500) // ArbitraryNumber { coefficient: 1.5, exponent: 3 }
|
|
239
320
|
*/
|
|
240
|
-
|
|
321
|
+
static tryFrom(value: number): Nullable<ArbitraryNumber>;
|
|
241
322
|
/**
|
|
242
|
-
*
|
|
323
|
+
* Returns a **new** instance equal to `a + b`.
|
|
243
324
|
*
|
|
244
|
-
*
|
|
245
|
-
* Only valid when |coefficient| is already in [1, 10) and exponent is correct.
|
|
246
|
-
* Do NOT use for unnormalised inputs - call new ArbitraryNumber(c, e) instead.
|
|
325
|
+
* Static methods always allocate — use instance `.add()` on hot paths.
|
|
247
326
|
*/
|
|
248
|
-
|
|
327
|
+
static add(a: ArbitraryNumber, b: ArbitraryNumber): ArbitraryNumber;
|
|
249
328
|
/**
|
|
250
|
-
*
|
|
329
|
+
* Returns a **new** instance equal to `a - b`.
|
|
330
|
+
*/
|
|
331
|
+
static sub(a: ArbitraryNumber, b: ArbitraryNumber): ArbitraryNumber;
|
|
332
|
+
/**
|
|
333
|
+
* Returns a **new** instance equal to `a * b`.
|
|
334
|
+
*/
|
|
335
|
+
static mul(a: ArbitraryNumber, b: ArbitraryNumber): ArbitraryNumber;
|
|
336
|
+
/**
|
|
337
|
+
* Returns a **new** instance equal to `a / b`.
|
|
251
338
|
*
|
|
252
|
-
*
|
|
253
|
-
* Algorithm: shift = floor(log10(|c|)); scale c by 10^-shift; adjust exponent.
|
|
254
|
-
* Cost: one Math.log10 call (~3-4 ns). This is the fundamental cost floor - logarithm
|
|
255
|
-
* is the only way to compute magnitude in JavaScript.
|
|
339
|
+
* @throws `"Division by zero"` when `b` is zero.
|
|
256
340
|
*/
|
|
257
|
-
|
|
341
|
+
static div(a: ArbitraryNumber, b: ArbitraryNumber): ArbitraryNumber;
|
|
258
342
|
/**
|
|
259
|
-
*
|
|
343
|
+
* Adds `other` to this number in-place.
|
|
344
|
+
*
|
|
345
|
+
* When the exponent difference exceeds `defaults.scaleCutoff`, the smaller
|
|
346
|
+
* operand has no effect and `this` is returned unchanged.
|
|
260
347
|
*
|
|
261
|
-
*
|
|
262
|
-
* operand has no effect and the larger is returned as-is.
|
|
348
|
+
* **Mutates `this`. Returns `this`.**
|
|
263
349
|
*
|
|
264
350
|
* @example
|
|
265
|
-
*
|
|
351
|
+
* gold.add(drop); // gold is mutated
|
|
266
352
|
*/
|
|
267
|
-
add(other: ArbitraryNumber):
|
|
353
|
+
add(other: ArbitraryNumber): this;
|
|
268
354
|
/**
|
|
269
|
-
*
|
|
355
|
+
* Subtracts `other` from this number in-place.
|
|
270
356
|
*
|
|
271
|
-
*
|
|
272
|
-
* new ArbitraryNumber(3.5, 3).sub(new ArbitraryNumber(1.5, 3)); // 2*10^3
|
|
357
|
+
* **Mutates `this`. Returns `this`.**
|
|
273
358
|
*/
|
|
274
|
-
sub(other: ArbitraryNumber):
|
|
359
|
+
sub(other: ArbitraryNumber): this;
|
|
275
360
|
/**
|
|
276
|
-
*
|
|
361
|
+
* Multiplies this number by `other` in-place.
|
|
277
362
|
*
|
|
278
|
-
*
|
|
279
|
-
* new ArbitraryNumber(2, 3).mul(new ArbitraryNumber(3, 4)); // 6*10^7
|
|
363
|
+
* **Mutates `this`. Returns `this`.**
|
|
280
364
|
*/
|
|
281
|
-
mul(other: ArbitraryNumber):
|
|
365
|
+
mul(other: ArbitraryNumber): this;
|
|
282
366
|
/**
|
|
283
|
-
*
|
|
367
|
+
* Divides this number by `other` in-place.
|
|
284
368
|
*
|
|
285
|
-
*
|
|
286
|
-
* new ArbitraryNumber(6, 7).div(new ArbitraryNumber(3, 4)); // 2*10^3
|
|
369
|
+
* **Mutates `this`. Returns `this`.**
|
|
287
370
|
*
|
|
288
371
|
* @throws `"Division by zero"` when `other` is zero.
|
|
289
372
|
*/
|
|
290
|
-
div(other: ArbitraryNumber):
|
|
373
|
+
div(other: ArbitraryNumber): this;
|
|
291
374
|
/**
|
|
292
|
-
*
|
|
375
|
+
* Negates this number in-place.
|
|
293
376
|
*
|
|
294
|
-
*
|
|
295
|
-
* new ArbitraryNumber(1.5, 3).negate(); // -1.5*10^3
|
|
377
|
+
* **Mutates `this`. Returns `this`.**
|
|
296
378
|
*/
|
|
297
|
-
negate():
|
|
379
|
+
negate(): this;
|
|
298
380
|
/**
|
|
299
|
-
*
|
|
300
|
-
*
|
|
301
|
-
* Returns `this` unchanged when the number is already non-negative.
|
|
381
|
+
* Sets this number to its absolute value in-place.
|
|
302
382
|
*
|
|
303
|
-
*
|
|
304
|
-
* new ArbitraryNumber(-1.5, 3).abs(); // 1.5*10^3
|
|
383
|
+
* **Mutates `this`. Returns `this`.**
|
|
305
384
|
*/
|
|
306
|
-
abs():
|
|
385
|
+
abs(): this;
|
|
307
386
|
/**
|
|
308
|
-
*
|
|
387
|
+
* Raises this number to the power `n` in-place.
|
|
309
388
|
*
|
|
310
389
|
* Supports integer, fractional, and negative exponents.
|
|
311
|
-
* `x^0` always
|
|
390
|
+
* `x^0` always sets `this` to `1`, including `0^0` (by convention).
|
|
312
391
|
*
|
|
313
|
-
*
|
|
314
|
-
* new ArbitraryNumber(2, 3).pow(2); // 4*10^6
|
|
315
|
-
* new ArbitraryNumber(2, 0).pow(-1); // 5*10^-1 (= 0.5)
|
|
392
|
+
* **Mutates `this`. Returns `this`.**
|
|
316
393
|
*
|
|
317
|
-
* @param n - The exponent to raise this number to.
|
|
318
394
|
* @throws `"Zero cannot be raised to a negative power"` when this is zero and `n < 0`.
|
|
319
395
|
*/
|
|
320
|
-
pow(n: number):
|
|
396
|
+
pow(n: number): this;
|
|
321
397
|
/**
|
|
322
|
-
* Fused multiply-add: `(this * multiplier) + addend`.
|
|
398
|
+
* Fused multiply-add in-place: `this = (this * multiplier) + addend`.
|
|
323
399
|
*
|
|
324
|
-
* Faster than `.mul(multiplier).add(addend)`
|
|
325
|
-
* intermediate
|
|
400
|
+
* Faster than `.mul(multiplier).add(addend)` — one normalisation pass total, no
|
|
401
|
+
* intermediate allocation.
|
|
326
402
|
*
|
|
327
|
-
*
|
|
403
|
+
* **Mutates `this`. Returns `this`.**
|
|
404
|
+
*/
|
|
405
|
+
mulAdd(multiplier: ArbitraryNumber, addend: ArbitraryNumber): this;
|
|
406
|
+
/**
|
|
407
|
+
* @internal
|
|
408
|
+
* Computes `(this + sign * addendC * 10^addendE)` and writes the normalised
|
|
409
|
+
* result back into `this`. Used by `addMul` and `subMul` to share the alignment
|
|
410
|
+
* logic without duplication.
|
|
328
411
|
*
|
|
329
|
-
*
|
|
330
|
-
*
|
|
331
|
-
*
|
|
412
|
+
* Returns the sign-adjusted addend coefficient so callers can detect the
|
|
413
|
+
* zero-result case. Writes the intermediate normalised sum into `this.coefficient`
|
|
414
|
+
* / `this.exponent` ready for the subsequent multiply step.
|
|
332
415
|
*/
|
|
333
|
-
|
|
416
|
+
private _addScaledInto;
|
|
334
417
|
/**
|
|
335
|
-
* Fused add-multiply: `(this + addend) * multiplier`.
|
|
418
|
+
* Fused add-multiply in-place: `this = (this + addend) * multiplier`.
|
|
336
419
|
*
|
|
337
|
-
*
|
|
338
|
-
|
|
420
|
+
* **Mutates `this`. Returns `this`.**
|
|
421
|
+
*/
|
|
422
|
+
addMul(addend: ArbitraryNumber, multiplier: ArbitraryNumber): this;
|
|
423
|
+
/**
|
|
424
|
+
* Fused multiply-subtract in-place: `this = (this * multiplier) - subtrahend`.
|
|
339
425
|
*
|
|
340
|
-
*
|
|
426
|
+
* **Mutates `this`. Returns `this`.**
|
|
427
|
+
*/
|
|
428
|
+
mulSub(multiplier: ArbitraryNumber, subtrahend: ArbitraryNumber): this;
|
|
429
|
+
/**
|
|
430
|
+
* Fused subtract-multiply in-place: `this = (this - subtrahend) * multiplier`.
|
|
341
431
|
*
|
|
342
|
-
*
|
|
343
|
-
* // Equivalent to base.add(bonus).mul(multiplier) but ~20-25% faster
|
|
344
|
-
* const upgraded = baseValue.addMul(bonus, multiplier);
|
|
432
|
+
* **Mutates `this`. Returns `this`.**
|
|
345
433
|
*/
|
|
346
|
-
|
|
434
|
+
subMul(subtrahend: ArbitraryNumber, multiplier: ArbitraryNumber): this;
|
|
347
435
|
/**
|
|
348
|
-
* Fused
|
|
436
|
+
* Fused divide-add in-place: `this = (this / divisor) + addend`.
|
|
349
437
|
*
|
|
350
|
-
*
|
|
438
|
+
* **Mutates `this`. Returns `this`.**
|
|
351
439
|
*
|
|
352
|
-
*
|
|
440
|
+
* @throws `"Division by zero"` when divisor is zero.
|
|
353
441
|
*/
|
|
354
|
-
|
|
442
|
+
divAdd(divisor: ArbitraryNumber, addend: ArbitraryNumber): this;
|
|
355
443
|
/**
|
|
356
|
-
* Fused
|
|
444
|
+
* Fused multiply-divide in-place: `this = (this * multiplier) / divisor`.
|
|
357
445
|
*
|
|
358
|
-
*
|
|
446
|
+
* **Mutates `this`. Returns `this`.**
|
|
359
447
|
*
|
|
360
|
-
*
|
|
448
|
+
* @throws `"Division by zero"` when divisor is zero.
|
|
361
449
|
*/
|
|
362
|
-
|
|
450
|
+
mulDiv(multiplier: ArbitraryNumber, divisor: ArbitraryNumber): this;
|
|
363
451
|
/**
|
|
364
|
-
*
|
|
452
|
+
* Efficiently sums an array of `ArbitraryNumber`s in a single pass.
|
|
365
453
|
*
|
|
366
|
-
*
|
|
454
|
+
* Maintains a running pivot exponent and rescales the accumulator when a larger
|
|
455
|
+
* exponent is encountered — one pass, no pre-scan needed.
|
|
367
456
|
*
|
|
368
|
-
*
|
|
457
|
+
* Empty array returns `Zero`. Single element returned as-is (no clone).
|
|
458
|
+
*/
|
|
459
|
+
static sumArray(numbers: ArbitraryNumber[]): ArbitraryNumber;
|
|
460
|
+
/**
|
|
461
|
+
* Multiplies an array of `ArbitraryNumber`s in a single pass.
|
|
369
462
|
*
|
|
370
|
-
*
|
|
463
|
+
* Empty array returns `One`. Single element returned as-is.
|
|
464
|
+
*/
|
|
465
|
+
static productArray(numbers: ArbitraryNumber[]): ArbitraryNumber;
|
|
466
|
+
/**
|
|
467
|
+
* Returns the largest value in an array. Empty array returns `Zero`.
|
|
468
|
+
*/
|
|
469
|
+
static maxOfArray(numbers: ArbitraryNumber[]): ArbitraryNumber;
|
|
470
|
+
/**
|
|
471
|
+
* Returns the smallest value in an array. Empty array returns `Zero`.
|
|
371
472
|
*/
|
|
372
|
-
|
|
473
|
+
static minOfArray(numbers: ArbitraryNumber[]): ArbitraryNumber;
|
|
373
474
|
/**
|
|
374
|
-
*
|
|
475
|
+
* Rounds down to the nearest integer in-place (floor toward −∞).
|
|
375
476
|
*
|
|
376
|
-
* **
|
|
377
|
-
|
|
378
|
-
|
|
477
|
+
* **Mutates `this`. Returns `this`.**
|
|
478
|
+
*/
|
|
479
|
+
floor(): this;
|
|
480
|
+
/**
|
|
481
|
+
* Rounds up to the nearest integer in-place (ceil toward +∞).
|
|
379
482
|
*
|
|
380
|
-
*
|
|
381
|
-
|
|
483
|
+
* **Mutates `this`. Returns `this`.**
|
|
484
|
+
*/
|
|
485
|
+
ceil(): this;
|
|
486
|
+
/**
|
|
487
|
+
* Rounds to the nearest integer in-place.
|
|
382
488
|
*
|
|
383
|
-
*
|
|
489
|
+
* Uses `Math.round` semantics: half-values round toward positive infinity
|
|
490
|
+
* (`0.5 → 1`, `-0.5 → 0`). This matches JavaScript's built-in convention.
|
|
384
491
|
*
|
|
385
|
-
*
|
|
386
|
-
|
|
492
|
+
* **Mutates `this`. Returns `this`.**
|
|
493
|
+
*/
|
|
494
|
+
round(): this;
|
|
495
|
+
/**
|
|
496
|
+
* Truncates toward zero in-place.
|
|
387
497
|
*
|
|
388
|
-
*
|
|
498
|
+
* **Mutates `this`. Returns `this`.**
|
|
389
499
|
*/
|
|
390
|
-
|
|
500
|
+
trunc(): this;
|
|
501
|
+
/**
|
|
502
|
+
* Returns √this in-place.
|
|
503
|
+
*
|
|
504
|
+
* **Mutates `this`. Returns `this`.**
|
|
505
|
+
*
|
|
506
|
+
* @throws `"Square root of negative number"` when this is negative.
|
|
507
|
+
*/
|
|
508
|
+
sqrt(): this;
|
|
509
|
+
/**
|
|
510
|
+
* Returns ∛this in-place.
|
|
511
|
+
*
|
|
512
|
+
* **Mutates `this`. Returns `this`.**
|
|
513
|
+
*/
|
|
514
|
+
cbrt(): this;
|
|
515
|
+
/**
|
|
516
|
+
* Returns `log10(this)` as a plain `number`.
|
|
517
|
+
*
|
|
518
|
+
* @throws `"Logarithm of zero is undefined"` when this is zero.
|
|
519
|
+
* @throws `"Logarithm of a negative number is undefined"` when this is negative.
|
|
520
|
+
*/
|
|
521
|
+
log10(): number;
|
|
522
|
+
/**
|
|
523
|
+
* Returns `log_base(this)` as a plain `number`.
|
|
524
|
+
*
|
|
525
|
+
* @param base - Must be positive and not 1.
|
|
526
|
+
* @throws `"Logarithm base must be positive and not 1"` for invalid base.
|
|
527
|
+
*/
|
|
528
|
+
log(base: number): number;
|
|
529
|
+
/**
|
|
530
|
+
* Returns `ln(this)` as a plain `number`.
|
|
531
|
+
*/
|
|
532
|
+
ln(): number;
|
|
533
|
+
/**
|
|
534
|
+
* Returns `10^n` as a new `ArbitraryNumber`.
|
|
535
|
+
*
|
|
536
|
+
* @throws `"ArbitraryNumber.exp10: n must be finite"` for non-finite `n`.
|
|
537
|
+
*/
|
|
538
|
+
static exp10(n: number): ArbitraryNumber;
|
|
391
539
|
/**
|
|
392
540
|
* Compares this number to `other`.
|
|
393
541
|
*
|
|
394
542
|
* @returns `1` if `this > other`, `-1` if `this < other`, `0` if equal.
|
|
395
|
-
*
|
|
396
|
-
* @example
|
|
397
|
-
* new ArbitraryNumber(1, 4).compareTo(new ArbitraryNumber(9, 3)); // 1 (10000 > 9000)
|
|
398
|
-
* new ArbitraryNumber(-1, 4).compareTo(new ArbitraryNumber(1, 3)); // -1 (-10000 < 1000)
|
|
399
543
|
*/
|
|
400
544
|
compareTo(other: ArbitraryNumber): number;
|
|
401
545
|
/** Returns `true` if `this > other`. */
|
|
@@ -409,156 +553,134 @@ declare class ArbitraryNumber implements NormalizedNumber {
|
|
|
409
553
|
/** Returns `true` if `this === other` in value. */
|
|
410
554
|
equals(other: ArbitraryNumber): boolean;
|
|
411
555
|
/**
|
|
412
|
-
*
|
|
413
|
-
*
|
|
414
|
-
* Numbers with `exponent >= PrecisionCutoff` are already integers at that scale
|
|
415
|
-
* and are returned unchanged.
|
|
416
|
-
*
|
|
417
|
-
* @example
|
|
418
|
-
* new ArbitraryNumber(1.7, 0).floor(); // 1
|
|
419
|
-
* new ArbitraryNumber(-1.7, 0).floor(); // -2
|
|
420
|
-
*/
|
|
421
|
-
floor(): ArbitraryNumber;
|
|
422
|
-
/**
|
|
423
|
-
* Returns the smallest integer greater than or equal to this number (ceil toward +Infinity).
|
|
424
|
-
*
|
|
425
|
-
* Numbers with `exponent >= PrecisionCutoff` are already integers at that scale
|
|
426
|
-
* and are returned unchanged.
|
|
427
|
-
*
|
|
428
|
-
* @example
|
|
429
|
-
* new ArbitraryNumber(1.2, 0).ceil(); // 2
|
|
430
|
-
* new ArbitraryNumber(-1.7, 0).ceil(); // -1
|
|
556
|
+
* Clamps `value` to the inclusive range `[min, max]`. Returns one of the three
|
|
557
|
+
* inputs (no allocation).
|
|
431
558
|
*/
|
|
432
|
-
|
|
559
|
+
static clamp(value: ArbitraryNumber, min: ArbitraryNumber, max: ArbitraryNumber): ArbitraryNumber;
|
|
560
|
+
/** Returns the smaller of `a` and `b`. */
|
|
561
|
+
static min(a: ArbitraryNumber, b: ArbitraryNumber): ArbitraryNumber;
|
|
562
|
+
/** Returns the larger of `a` and `b`. */
|
|
563
|
+
static max(a: ArbitraryNumber, b: ArbitraryNumber): ArbitraryNumber;
|
|
433
564
|
/**
|
|
434
|
-
*
|
|
435
|
-
*
|
|
436
|
-
* @example
|
|
437
|
-
* ArbitraryNumber.clamp(new ArbitraryNumber(5, 2), new ArbitraryNumber(1, 3), new ArbitraryNumber(2, 3)); // 1*10^3 (500 clamped to [1000, 2000])
|
|
565
|
+
* Linear interpolation: `a + (b - a) * t`.
|
|
438
566
|
*
|
|
439
|
-
*
|
|
440
|
-
*
|
|
441
|
-
* @param max - Upper bound (inclusive).
|
|
567
|
+
* Returns `a` unchanged when `t === 0`, `b` unchanged when `t === 1`.
|
|
568
|
+
* All other values of `t` allocate and return a fresh instance.
|
|
442
569
|
*/
|
|
443
|
-
static
|
|
570
|
+
static lerp(a: ArbitraryNumber, b: ArbitraryNumber, t: number): ArbitraryNumber;
|
|
444
571
|
/**
|
|
445
|
-
*
|
|
446
|
-
* @example ArbitraryNumber.min(a, b)
|
|
572
|
+
* Runs `fn` with `defaults.scaleCutoff` temporarily set to `cutoff`, then restores it.
|
|
447
573
|
*/
|
|
448
|
-
static
|
|
574
|
+
static withPrecision<T>(cutoff: number, fn: () => T): T;
|
|
575
|
+
/** Returns `true` when this number is zero. */
|
|
576
|
+
isZero(): boolean;
|
|
577
|
+
/** Returns `true` when this number is strictly positive. */
|
|
578
|
+
isPositive(): boolean;
|
|
579
|
+
/** Returns `true` when this number is strictly negative. */
|
|
580
|
+
isNegative(): boolean;
|
|
449
581
|
/**
|
|
450
|
-
* Returns
|
|
451
|
-
*
|
|
582
|
+
* Returns `true` when this number has no fractional part.
|
|
583
|
+
* Numbers with `exponent >= scaleCutoff` are always considered integers.
|
|
452
584
|
*/
|
|
453
|
-
|
|
585
|
+
isInteger(): boolean;
|
|
454
586
|
/**
|
|
455
|
-
*
|
|
456
|
-
*
|
|
457
|
-
* Used for smooth animations and tweening in game UIs.
|
|
458
|
-
* `t = 0` returns `a`; `t = 1` returns `b`.
|
|
459
|
-
*
|
|
460
|
-
* @param t - Interpolation factor as a plain `number`. Values outside [0, 1] are allowed (extrapolation).
|
|
461
|
-
* @example
|
|
462
|
-
* ArbitraryNumber.lerp(an(100), an(200), 0.5); // 150
|
|
587
|
+
* Returns `1` if positive, `-1` if negative, `0` if zero.
|
|
463
588
|
*/
|
|
464
|
-
|
|
589
|
+
sign(): Signum;
|
|
465
590
|
/**
|
|
466
|
-
*
|
|
591
|
+
* Returns a `FrozenArbitraryNumber` wrapping the same value.
|
|
467
592
|
*
|
|
468
|
-
*
|
|
469
|
-
*
|
|
470
|
-
* @example
|
|
471
|
-
* // Run financial calculation with higher precision
|
|
472
|
-
* const result = ArbitraryNumber.withPrecision(50, () => a.add(b));
|
|
593
|
+
* Mutating methods on the frozen instance throw `ArbitraryNumberMutationError`.
|
|
594
|
+
* Call `.clone()` on the frozen instance to get a fresh, mutable copy.
|
|
473
595
|
*/
|
|
474
|
-
|
|
596
|
+
freeze(): FrozenArbitraryNumber;
|
|
475
597
|
/**
|
|
476
|
-
*
|
|
477
|
-
*
|
|
478
|
-
* Because the number is stored as `c * 10^e`, this is computed exactly as
|
|
479
|
-
* `log10(c) + e` - no precision loss from the exponent.
|
|
480
|
-
*
|
|
481
|
-
* @example
|
|
482
|
-
* new ArbitraryNumber(1, 6).log10(); // 6
|
|
483
|
-
* new ArbitraryNumber(1.5, 3).log10(); // log10(1.5) + 3 ~ 3.176
|
|
598
|
+
* Converts to a plain JavaScript `number`.
|
|
484
599
|
*
|
|
485
|
-
*
|
|
486
|
-
*
|
|
600
|
+
* Returns `Infinity` for exponents beyond float64 range (>=308).
|
|
601
|
+
* Returns `0` for exponents below float64 range (<=-324).
|
|
487
602
|
*/
|
|
488
|
-
|
|
603
|
+
toNumber(): number;
|
|
489
604
|
/**
|
|
490
|
-
* Returns
|
|
605
|
+
* Returns a stable, minimal JSON representation: `{ c: number, e: number }`.
|
|
491
606
|
*
|
|
492
|
-
*
|
|
493
|
-
* For even exponents: `sqrt(c) * 10^(e/2)`.
|
|
494
|
-
* For odd exponents: `sqrt(c * 10) * 10^((e-1)/2)`.
|
|
495
|
-
*
|
|
496
|
-
* @throws `"Square root of negative number"` when this is negative.
|
|
497
|
-
* @example
|
|
498
|
-
* new ArbitraryNumber(4, 0).sqrt(); // 2
|
|
499
|
-
* new ArbitraryNumber(1, 4).sqrt(); // 1*10^2 (= 100)
|
|
607
|
+
* Round-trip guarantee: `ArbitraryNumber.fromJSON(x.toJSON()).equals(x)` is always `true`.
|
|
500
608
|
*/
|
|
501
|
-
|
|
609
|
+
toJSON(): ArbitraryNumberJson;
|
|
502
610
|
/**
|
|
503
|
-
* Returns
|
|
611
|
+
* Returns a compact string representation: `"<coefficient>|<exponent>"`.
|
|
504
612
|
*
|
|
505
|
-
*
|
|
506
|
-
* and are returned unchanged.
|
|
613
|
+
* Shorter than JSON for save-game serialisation. Reconstruct via `ArbitraryNumber.parse`.
|
|
507
614
|
*
|
|
508
615
|
* @example
|
|
509
|
-
*
|
|
510
|
-
* new ArbitraryNumber(1.4, 0).round(); // 1
|
|
511
|
-
* new ArbitraryNumber(-1.5, 0).round(); // -1 (half-up toward positive infinity)
|
|
616
|
+
* an(1500).toRawString() // "1.5|3"
|
|
512
617
|
*/
|
|
513
|
-
|
|
618
|
+
toRawString(): string;
|
|
514
619
|
/**
|
|
515
|
-
*
|
|
620
|
+
* Reconstructs an `ArbitraryNumber` from a `toJSON()` blob.
|
|
516
621
|
*
|
|
517
|
-
* @
|
|
518
|
-
* new ArbitraryNumber(1.5, 3).sign(); // 1
|
|
519
|
-
* new ArbitraryNumber(-1.5, 3).sign(); // -1
|
|
520
|
-
* ArbitraryNumber.Zero.sign(); // 0
|
|
622
|
+
* @throws `ArbitraryNumberInputError` when the object shape is invalid or values are non-finite.
|
|
521
623
|
*/
|
|
522
|
-
|
|
624
|
+
static fromJSON(obj: unknown): ArbitraryNumber;
|
|
523
625
|
/**
|
|
524
|
-
*
|
|
626
|
+
* Parses a string into an `ArbitraryNumber`.
|
|
525
627
|
*
|
|
526
|
-
*
|
|
527
|
-
*
|
|
528
|
-
*
|
|
628
|
+
* Accepted formats:
|
|
629
|
+
* - Raw pipe format: `"1.5|3"`, `"-2.5|-6"`
|
|
630
|
+
* - Scientific notation: `"1.5e+3"`, `"1.5E3"`
|
|
631
|
+
* - Plain decimal: `"1500"`, `"-0.003"`, `"0"`
|
|
529
632
|
*
|
|
530
|
-
* @
|
|
531
|
-
* new ArbitraryNumber(1.5, 3).toNumber(); // 1500
|
|
532
|
-
* new ArbitraryNumber(1, 400).toNumber(); // Infinity
|
|
633
|
+
* @throws `ArbitraryNumberInputError` for invalid or non-finite input.
|
|
533
634
|
*/
|
|
534
|
-
|
|
535
|
-
/** Returns `true` when this number is zero. */
|
|
536
|
-
isZero(): boolean;
|
|
537
|
-
/** Returns `true` when this number is strictly positive. */
|
|
538
|
-
isPositive(): boolean;
|
|
539
|
-
/** Returns `true` when this number is strictly negative. */
|
|
540
|
-
isNegative(): boolean;
|
|
635
|
+
static parse(s: string): ArbitraryNumber;
|
|
541
636
|
/**
|
|
542
|
-
*
|
|
543
|
-
*
|
|
637
|
+
* Allows implicit coercion via `+an(1500)` (returns `toNumber()`) and
|
|
638
|
+
* template literals / string concatenation (returns `toString()`).
|
|
544
639
|
*/
|
|
545
|
-
|
|
640
|
+
[Symbol.toPrimitive](hint: string): number | string;
|
|
546
641
|
/**
|
|
547
642
|
* Formats this number as a string using the given notation plugin.
|
|
548
643
|
*
|
|
549
|
-
* Defaults to
|
|
550
|
-
* `decimals` controls
|
|
551
|
-
*
|
|
552
|
-
* @example
|
|
553
|
-
* new ArbitraryNumber(1.5, 3).toString(); // "1.50e+3"
|
|
554
|
-
* new ArbitraryNumber(1.5, 3).toString(unitNotation); // "1.50 K"
|
|
555
|
-
* new ArbitraryNumber(1.5, 3).toString(unitNotation, 4); // "1.5000 K"
|
|
556
|
-
*
|
|
557
|
-
* @param notation - The formatting plugin to use.
|
|
558
|
-
* @param decimals - Number of decimal places to render. Defaults to `2`.
|
|
644
|
+
* Defaults to `scientificNotation` when no plugin is provided.
|
|
645
|
+
* `decimals` controls decimal places and defaults to `defaults.notationDecimals`.
|
|
559
646
|
*/
|
|
560
647
|
toString(notation?: NotationPlugin, decimals?: number): string;
|
|
561
648
|
}
|
|
649
|
+
/**
|
|
650
|
+
* An immutable wrapper around `ArbitraryNumber`.
|
|
651
|
+
*
|
|
652
|
+
* Created via `number.freeze()`. All mutating methods throw `ArbitraryNumberMutationError`.
|
|
653
|
+
* Call `.clone()` to get a fresh, mutable `ArbitraryNumber`.
|
|
654
|
+
*
|
|
655
|
+
* @example
|
|
656
|
+
* const frozen = gold.freeze();
|
|
657
|
+
* frozen.add(drop); // throws ArbitraryNumberMutationError
|
|
658
|
+
* const mutable = frozen.clone(); // fresh mutable copy
|
|
659
|
+
*/
|
|
660
|
+
declare class FrozenArbitraryNumber extends ArbitraryNumber {
|
|
661
|
+
/** @internal */
|
|
662
|
+
constructor(coefficient: number, exponent: number);
|
|
663
|
+
private _throwMutation;
|
|
664
|
+
add(_other: ArbitraryNumber): never;
|
|
665
|
+
sub(_other: ArbitraryNumber): never;
|
|
666
|
+
mul(_other: ArbitraryNumber): never;
|
|
667
|
+
div(_other: ArbitraryNumber): never;
|
|
668
|
+
negate(): never;
|
|
669
|
+
abs(): never;
|
|
670
|
+
pow(_n: number): never;
|
|
671
|
+
mulAdd(_m: ArbitraryNumber, _a: ArbitraryNumber): never;
|
|
672
|
+
addMul(_a: ArbitraryNumber, _m: ArbitraryNumber): never;
|
|
673
|
+
mulSub(_m: ArbitraryNumber, _s: ArbitraryNumber): never;
|
|
674
|
+
subMul(_s: ArbitraryNumber, _m: ArbitraryNumber): never;
|
|
675
|
+
divAdd(_d: ArbitraryNumber, _a: ArbitraryNumber): never;
|
|
676
|
+
mulDiv(_m: ArbitraryNumber, _d: ArbitraryNumber): never;
|
|
677
|
+
floor(): never;
|
|
678
|
+
ceil(): never;
|
|
679
|
+
round(): never;
|
|
680
|
+
trunc(): never;
|
|
681
|
+
sqrt(): never;
|
|
682
|
+
cbrt(): never;
|
|
683
|
+
}
|
|
562
684
|
|
|
563
685
|
/**
|
|
564
686
|
* Base class for all errors thrown by the arbitrary-numbers library.
|
|
@@ -602,111 +724,38 @@ declare class ArbitraryNumberDomainError extends ArbitraryNumberError {
|
|
|
602
724
|
readonly context: Record<string, number>;
|
|
603
725
|
constructor(message: string, context: Record<string, number>);
|
|
604
726
|
}
|
|
605
|
-
|
|
606
|
-
declare const an: AnFunction;
|
|
607
|
-
|
|
608
727
|
/**
|
|
609
|
-
*
|
|
610
|
-
*
|
|
611
|
-
* Each method mutates the accumulated value in-place and returns `this`,
|
|
612
|
-
* enabling a readable left-to-right pipeline with no expression-tree
|
|
613
|
-
* overhead. Every step delegates directly to the underlying
|
|
614
|
-
* `ArbitraryNumber` method - fused variants (`mulAdd`, `mulSub`, etc.)
|
|
615
|
-
* are available here too.
|
|
728
|
+
* Thrown when a mutating method is called on a frozen `ArbitraryNumber`.
|
|
616
729
|
*
|
|
617
730
|
* @example
|
|
618
|
-
*
|
|
619
|
-
*
|
|
620
|
-
*
|
|
621
|
-
*
|
|
622
|
-
*
|
|
623
|
-
*
|
|
624
|
-
* @remarks
|
|
625
|
-
* No deferred execution - each call runs immediately. Overhead vs direct
|
|
626
|
-
* method chaining is a single extra method call + `return this` per step
|
|
627
|
-
* (~1-2 ns). Use fused ops for hot inner loops; the builder is optimised
|
|
628
|
-
* for readability in complex multi-step formulas.
|
|
731
|
+
* try {
|
|
732
|
+
* frozen.add(other);
|
|
733
|
+
* } catch (e) {
|
|
734
|
+
* if (e instanceof ArbitraryNumberMutationError) { ... }
|
|
735
|
+
* }
|
|
629
736
|
*/
|
|
630
|
-
declare class
|
|
631
|
-
|
|
632
|
-
private constructor();
|
|
633
|
-
/** Creates an `AnChain` from an `ArbitraryNumber` or a plain `number`. */
|
|
634
|
-
static from(value: ArbitraryNumber | number): AnChain;
|
|
635
|
-
/** Adds `other` to the accumulated value. */
|
|
636
|
-
add(other: ArbitraryNumber): this;
|
|
637
|
-
/** Subtracts `other` from the accumulated value. */
|
|
638
|
-
sub(other: ArbitraryNumber): this;
|
|
639
|
-
/** Multiplies the accumulated value by `other`. */
|
|
640
|
-
mul(other: ArbitraryNumber): this;
|
|
641
|
-
/** Divides the accumulated value by `other`. */
|
|
642
|
-
div(other: ArbitraryNumber): this;
|
|
643
|
-
/** Raises the accumulated value to `exp`. */
|
|
644
|
-
pow(exp: number): this;
|
|
645
|
-
/** `(this * mult) + add` */
|
|
646
|
-
mulAdd(mult: ArbitraryNumber, add: ArbitraryNumber): this;
|
|
647
|
-
/** `(this + add) * mult` */
|
|
648
|
-
addMul(add: ArbitraryNumber, mult: ArbitraryNumber): this;
|
|
649
|
-
/** `(this * mult) - sub` */
|
|
650
|
-
mulSub(mult: ArbitraryNumber, sub: ArbitraryNumber): this;
|
|
651
|
-
/** `(this - sub) * mult` */
|
|
652
|
-
subMul(sub: ArbitraryNumber, mult: ArbitraryNumber): this;
|
|
653
|
-
/** `(this / div) + add` */
|
|
654
|
-
divAdd(div: ArbitraryNumber, add: ArbitraryNumber): this;
|
|
655
|
-
/** Absolute value. */
|
|
656
|
-
abs(): this;
|
|
657
|
-
/** Negates the accumulated value. */
|
|
658
|
-
neg(): this;
|
|
659
|
-
/** Square root of the accumulated value. */
|
|
660
|
-
sqrt(): this;
|
|
661
|
-
/** Rounds down to the nearest integer. */
|
|
662
|
-
floor(): this;
|
|
663
|
-
/** Rounds up to the nearest integer. */
|
|
664
|
-
ceil(): this;
|
|
665
|
-
/** Rounds to the nearest integer. */
|
|
666
|
-
round(): this;
|
|
667
|
-
/** Returns the accumulated `ArbitraryNumber` result. */
|
|
668
|
-
done(): ArbitraryNumber;
|
|
737
|
+
declare class ArbitraryNumberMutationError extends ArbitraryNumberDomainError {
|
|
738
|
+
constructor(message: string);
|
|
669
739
|
}
|
|
670
|
-
/**
|
|
671
|
-
* Creates an {@link AnChain} builder starting from `value`.
|
|
672
|
-
*
|
|
673
|
-
* Mirrors the `an` factory shorthand.
|
|
674
|
-
*
|
|
675
|
-
* @example
|
|
676
|
-
* import { chain, an } from 'arbitrary-numbers';
|
|
677
|
-
*
|
|
678
|
-
* const result = chain(an(1.5, 6))
|
|
679
|
-
* .mulAdd(multiplier, bonus)
|
|
680
|
-
* .floor()
|
|
681
|
-
* .done();
|
|
682
|
-
*/
|
|
683
|
-
declare function chain(value: ArbitraryNumber | number): AnChain;
|
|
684
740
|
|
|
685
|
-
|
|
741
|
+
declare const an: AnFunction;
|
|
742
|
+
|
|
743
|
+
type FormulaStep = (value: ArbitraryNumber) => void;
|
|
686
744
|
/**
|
|
687
745
|
* A reusable, named pipeline of `ArbitraryNumber` operations.
|
|
688
746
|
*
|
|
689
|
-
*
|
|
690
|
-
*
|
|
691
|
-
* and runs them only when {@link apply} is called. The same formula can be
|
|
692
|
-
* applied to any number of values without re-defining the pipeline.
|
|
747
|
+
* `AnFormula` stores operations as closures and runs them on `.apply()` or `.applyInPlace()`.
|
|
748
|
+
* The same formula can be applied to any number of values without re-defining the pipeline.
|
|
693
749
|
*
|
|
694
|
-
* Each builder method returns a **new** `AnFormula`
|
|
695
|
-
* unchanged. This makes branching and composition safe:
|
|
750
|
+
* Each builder method returns a **new** `AnFormula` — the original is unchanged.
|
|
696
751
|
*
|
|
697
752
|
* @example
|
|
698
|
-
* const base = formula().mul(an(2));
|
|
699
|
-
* const withFloor = base.floor(); // new formula - base is unchanged
|
|
700
|
-
* const withCeil = base.ceil(); // another branch from base
|
|
701
|
-
*
|
|
702
|
-
* @example
|
|
703
|
-
* // Define once, apply to many values
|
|
704
753
|
* const armorReduction = formula("Armor Reduction")
|
|
705
754
|
* .subMul(armor, an(0.75))
|
|
706
755
|
* .floor();
|
|
707
756
|
*
|
|
708
|
-
* const physDamage = armorReduction.apply(physBase);
|
|
709
|
-
*
|
|
757
|
+
* const physDamage = armorReduction.apply(physBase); // physBase unchanged
|
|
758
|
+
* armorReduction.applyInPlace(enemyAtk); // enemyAtk mutated
|
|
710
759
|
*
|
|
711
760
|
* @example
|
|
712
761
|
* // Compose formulas
|
|
@@ -715,23 +764,14 @@ type FormulaStep = (value: ArbitraryNumber) => ArbitraryNumber;
|
|
|
715
764
|
* const result = full.apply(baseDamage);
|
|
716
765
|
*/
|
|
717
766
|
declare class AnFormula {
|
|
718
|
-
private readonly _name
|
|
767
|
+
private readonly _name;
|
|
719
768
|
private readonly steps;
|
|
720
|
-
/**
|
|
721
|
-
|
|
722
|
-
*/
|
|
723
|
-
constructor(name?: string, steps?: ReadonlyArray<FormulaStep>);
|
|
769
|
+
/** Prefer the {@link formula} factory function over calling this directly. */
|
|
770
|
+
constructor(name?: Maybe<string>, steps?: ReadonlyArray<FormulaStep>);
|
|
724
771
|
/** The name passed to {@link formula}, if any. */
|
|
725
|
-
get name(): string
|
|
772
|
+
get name(): Maybe<string>;
|
|
726
773
|
/**
|
|
727
774
|
* Returns a copy of this formula with a new name, leaving the original unchanged.
|
|
728
|
-
*
|
|
729
|
-
* @param name - The new name.
|
|
730
|
-
* @example
|
|
731
|
-
* const base = formula().mul(an(2));
|
|
732
|
-
* const named = base.named("Double");
|
|
733
|
-
* named.name // "Double"
|
|
734
|
-
* base.name // undefined
|
|
735
775
|
*/
|
|
736
776
|
named(name: string): AnFormula;
|
|
737
777
|
private step;
|
|
@@ -757,7 +797,7 @@ declare class AnFormula {
|
|
|
757
797
|
divAdd(div: ArbitraryNumber, add: ArbitraryNumber): AnFormula;
|
|
758
798
|
/** Appends `abs()` to the pipeline. */
|
|
759
799
|
abs(): AnFormula;
|
|
760
|
-
/** Appends `
|
|
800
|
+
/** Appends `negate()` to the pipeline. */
|
|
761
801
|
neg(): AnFormula;
|
|
762
802
|
/** Appends `sqrt()` to the pipeline. */
|
|
763
803
|
sqrt(): AnFormula;
|
|
@@ -771,52 +811,44 @@ declare class AnFormula {
|
|
|
771
811
|
* Returns a new formula that first applies `this`, then applies `next`.
|
|
772
812
|
*
|
|
773
813
|
* Neither operand is mutated.
|
|
774
|
-
*
|
|
775
|
-
* @param next - The formula to apply after `this`.
|
|
776
|
-
* @example
|
|
777
|
-
* const full = armorReduction.then(critBonus);
|
|
778
|
-
* const result = full.apply(baseDamage);
|
|
779
814
|
*/
|
|
780
815
|
then(next: AnFormula): AnFormula;
|
|
781
816
|
/**
|
|
782
|
-
*
|
|
817
|
+
* Clones `value` once, runs the pipeline against the clone, and returns it.
|
|
783
818
|
*
|
|
784
|
-
* The
|
|
819
|
+
* The original `value` is never mutated.
|
|
785
820
|
*
|
|
786
|
-
* @param value - The starting value. Plain `number` is coerced via `ArbitraryNumber.from`.
|
|
787
|
-
* @throws `"ArbitraryNumber.from: value must be finite"` when a plain `number` is non-finite.
|
|
788
821
|
* @example
|
|
789
|
-
* const damage = damageFormula.apply(
|
|
790
|
-
* const scaled = damageFormula.apply(boostedBase);
|
|
822
|
+
* const damage = damageFormula.apply(playerAtk); // playerAtk unchanged
|
|
791
823
|
*/
|
|
792
824
|
apply(value: ArbitraryNumber | number): ArbitraryNumber;
|
|
825
|
+
/**
|
|
826
|
+
* Runs the pipeline directly against `value`, mutating it in-place.
|
|
827
|
+
*
|
|
828
|
+
* Use on hot paths where you don't need to preserve the original value.
|
|
829
|
+
*
|
|
830
|
+
* @example
|
|
831
|
+
* damageFormula.applyInPlace(enemyAtk); // enemyAtk is mutated
|
|
832
|
+
*/
|
|
833
|
+
applyInPlace(value: ArbitraryNumber): void;
|
|
793
834
|
}
|
|
794
835
|
/**
|
|
795
836
|
* Creates an {@link AnFormula} pipeline, optionally named.
|
|
796
837
|
*
|
|
797
|
-
* Build the pipeline by chaining methods
|
|
798
|
-
*
|
|
799
|
-
* to run the pipeline against a value.
|
|
838
|
+
* Build the pipeline by chaining methods — each returns a new `AnFormula`.
|
|
839
|
+
* Call {@link AnFormula.apply} or {@link AnFormula.applyInPlace} to run it.
|
|
800
840
|
*
|
|
801
|
-
* @param name - Optional label, available via {@link AnFormula.name} for debugging.
|
|
802
841
|
* @example
|
|
803
842
|
* import { formula, an } from 'arbitrary-numbers';
|
|
804
843
|
*
|
|
805
844
|
* const armorReduction = formula("Armor Reduction")
|
|
806
|
-
* .subMul(armor, an(0.75))
|
|
845
|
+
* .subMul(armor, an(0.75))
|
|
807
846
|
* .floor();
|
|
808
847
|
*
|
|
809
|
-
* const critBonus = formula("Crit Bonus").mul(critMult).ceil();
|
|
810
|
-
*
|
|
811
|
-
* // Reuse across many values
|
|
812
848
|
* const physDmg = armorReduction.apply(physBase);
|
|
813
|
-
*
|
|
814
|
-
*
|
|
815
|
-
* // Compose
|
|
816
|
-
* const full = armorReduction.then(critBonus);
|
|
817
|
-
* const result = full.apply(baseDamage);
|
|
849
|
+
* armorReduction.applyInPlace(tempValue);
|
|
818
850
|
*/
|
|
819
|
-
declare function formula(name?: string): AnFormula;
|
|
851
|
+
declare function formula(name?: Maybe<string>): AnFormula;
|
|
820
852
|
|
|
821
853
|
/**
|
|
822
854
|
* Formats numbers using standard scientific notation: `"1.50e+3"`, `"1.50e-5"`.
|
|
@@ -988,14 +1020,23 @@ declare const letterNotation: AlphabetNotation;
|
|
|
988
1020
|
declare class UnitNotation extends SuffixNotationBase {
|
|
989
1021
|
protected readonly fallback?: SuffixProvider;
|
|
990
1022
|
protected readonly units: UnitArray;
|
|
1023
|
+
/** The highest tier index that has a defined unit in `units`. Used to offset fallback calls. */
|
|
1024
|
+
private readonly lastDefinedTier;
|
|
1025
|
+
private readonly offsetFallback;
|
|
991
1026
|
/**
|
|
992
1027
|
* @param options - Tier-indexed unit array, optional suffix fallback plugin, and separator.
|
|
993
1028
|
* `separator` defaults to `" "` (a space between number and unit symbol).
|
|
1029
|
+
* `offsetFallback` defaults to `true` — the fallback tier is offset so its suffixes
|
|
1030
|
+
* are visually distinct from any low-tier suffixes the same fallback would produce.
|
|
994
1031
|
*/
|
|
995
1032
|
constructor(options: UnitNotationOptions);
|
|
996
1033
|
/**
|
|
997
1034
|
* Returns the suffix for the given tier: the own unit symbol if defined,
|
|
998
|
-
* otherwise the fallback's suffix
|
|
1035
|
+
* otherwise the fallback's suffix (offset by the last defined tier when
|
|
1036
|
+
* `offsetFallback` is `true`), otherwise `""`.
|
|
1037
|
+
*
|
|
1038
|
+
* The offset ensures fallback suffixes start at tier 1 of the fallback's sequence,
|
|
1039
|
+
* avoiding visual ambiguity with low-tier suffixes from the same fallback plugin.
|
|
999
1040
|
*
|
|
1000
1041
|
* @param tier - The exponent tier (`Math.floor(exponent / 3)`).
|
|
1001
1042
|
* @returns The suffix string, or `""` if neither own units nor fallback cover this tier.
|
|
@@ -1051,18 +1092,15 @@ declare class ArbitraryNumberGuard {
|
|
|
1051
1092
|
*/
|
|
1052
1093
|
static isArbitraryNumber(obj: unknown): obj is ArbitraryNumber;
|
|
1053
1094
|
/**
|
|
1054
|
-
* Returns `true` if `obj` has the shape
|
|
1055
|
-
* (i.e. has numeric `coefficient` and `exponent` properties).
|
|
1056
|
-
*
|
|
1057
|
-
* Note: both `ArbitraryNumber` instances and plain objects with the right
|
|
1058
|
-
* shape will pass this check. Use {@link isArbitraryNumber} when you need
|
|
1059
|
-
* to distinguish between the two.
|
|
1095
|
+
* Returns `true` if `obj` has the shape `{ coefficient: number; exponent: number }`.
|
|
1060
1096
|
*
|
|
1061
|
-
*
|
|
1062
|
-
*
|
|
1063
|
-
* `typeof exponent === "number"`.
|
|
1097
|
+
* Both `ArbitraryNumber` instances and plain objects with the right shape pass this
|
|
1098
|
+
* check. Use {@link isArbitraryNumber} to distinguish the two.
|
|
1064
1099
|
*/
|
|
1065
|
-
static isNormalizedNumber(obj: unknown): obj is
|
|
1100
|
+
static isNormalizedNumber(obj: unknown): obj is {
|
|
1101
|
+
coefficient: number;
|
|
1102
|
+
exponent: number;
|
|
1103
|
+
};
|
|
1066
1104
|
/**
|
|
1067
1105
|
* Returns `true` if `obj` is an {@link ArbitraryNumber} with a value of zero.
|
|
1068
1106
|
*
|
|
@@ -1072,102 +1110,10 @@ declare class ArbitraryNumberGuard {
|
|
|
1072
1110
|
static isZero(obj: unknown): boolean;
|
|
1073
1111
|
}
|
|
1074
1112
|
|
|
1075
|
-
/**
|
|
1076
|
-
* A value that can be either a plain `number` or an `ArbitraryNumber`.
|
|
1077
|
-
*/
|
|
1078
|
-
type ArbitraryNumberish = ArbitraryNumber | number;
|
|
1079
|
-
|
|
1080
|
-
/**
|
|
1081
|
-
* Convenience helpers for mixed `number | ArbitraryNumber` inputs.
|
|
1082
|
-
*
|
|
1083
|
-
* Each method accepts either type and coerces plain `number` values via
|
|
1084
|
-
* {@link ArbitraryNumber.from} before delegating to the corresponding instance method.
|
|
1085
|
-
*
|
|
1086
|
-
* Prefer `ArbitraryNumber` instance methods directly on hot paths - this class is
|
|
1087
|
-
* intended for system boundaries (event handlers, serialisation, UI callbacks) where
|
|
1088
|
-
* the input type is unknown.
|
|
1089
|
-
*
|
|
1090
|
-
* @example
|
|
1091
|
-
* import { ArbitraryNumberOps as ops } from "arbitrary-numbers";
|
|
1092
|
-
* ops.add(1500, 2500) // ArbitraryNumber (4000)
|
|
1093
|
-
* ops.mul(an(2, 0), 5) // ArbitraryNumber (10)
|
|
1094
|
-
* ops.from(1_500_000) // ArbitraryNumber { coefficient: 1.5, exponent: 6 }
|
|
1095
|
-
*/
|
|
1096
|
-
declare class ArbitraryNumberOps {
|
|
1097
|
-
/**
|
|
1098
|
-
* Converts `value` to an `ArbitraryNumber`, returning it unchanged if it already is one.
|
|
1099
|
-
*
|
|
1100
|
-
* @param value - A plain `number` or an existing `ArbitraryNumber`.
|
|
1101
|
-
* @returns The corresponding `ArbitraryNumber`.
|
|
1102
|
-
*/
|
|
1103
|
-
static from(value: ArbitraryNumberish): ArbitraryNumber;
|
|
1104
|
-
/**
|
|
1105
|
-
* Returns `left + right`, coercing both operands as needed.
|
|
1106
|
-
*
|
|
1107
|
-
* @param left - The augend.
|
|
1108
|
-
* @param right - The addend.
|
|
1109
|
-
* @example
|
|
1110
|
-
* ops.add(1500, 2500) // ArbitraryNumber (4000)
|
|
1111
|
-
*/
|
|
1112
|
-
static add(left: ArbitraryNumberish, right: ArbitraryNumberish): ArbitraryNumber;
|
|
1113
|
-
/**
|
|
1114
|
-
* Returns `left - right`, coercing both operands as needed.
|
|
1115
|
-
*
|
|
1116
|
-
* @param left - The minuend.
|
|
1117
|
-
* @param right - The subtrahend.
|
|
1118
|
-
* @example
|
|
1119
|
-
* ops.sub(5000, 1500) // ArbitraryNumber (3500)
|
|
1120
|
-
*/
|
|
1121
|
-
static sub(left: ArbitraryNumberish, right: ArbitraryNumberish): ArbitraryNumber;
|
|
1122
|
-
/**
|
|
1123
|
-
* Returns `left * right`, coercing both operands as needed.
|
|
1124
|
-
*
|
|
1125
|
-
* @param left - The multiplicand.
|
|
1126
|
-
* @param right - The multiplier.
|
|
1127
|
-
* @example
|
|
1128
|
-
* ops.mul(an(1, 3), 5) // ArbitraryNumber (5000)
|
|
1129
|
-
*/
|
|
1130
|
-
static mul(left: ArbitraryNumberish, right: ArbitraryNumberish): ArbitraryNumber;
|
|
1131
|
-
/**
|
|
1132
|
-
* Returns `left / right`, coercing both operands as needed.
|
|
1133
|
-
*
|
|
1134
|
-
* @param left - The dividend.
|
|
1135
|
-
* @param right - The divisor.
|
|
1136
|
-
* @throws `"Division by zero"` when `right` is zero.
|
|
1137
|
-
* @example
|
|
1138
|
-
* ops.div(an(1, 6), 1000) // ArbitraryNumber (1000)
|
|
1139
|
-
*/
|
|
1140
|
-
static div(left: ArbitraryNumberish, right: ArbitraryNumberish): ArbitraryNumber;
|
|
1141
|
-
/**
|
|
1142
|
-
* Compares `left` to `right`.
|
|
1143
|
-
*
|
|
1144
|
-
* @param left - The left operand.
|
|
1145
|
-
* @param right - The right operand.
|
|
1146
|
-
* @returns `1` if `left > right`, `-1` if `left < right`, `0` if equal.
|
|
1147
|
-
* @example
|
|
1148
|
-
* ops.compare(5000, 1500) // 1
|
|
1149
|
-
*/
|
|
1150
|
-
static compare(left: ArbitraryNumberish, right: ArbitraryNumberish): number;
|
|
1151
|
-
/**
|
|
1152
|
-
* Clamps `value` to the inclusive range `[min, max]`, coercing all inputs as needed.
|
|
1153
|
-
*
|
|
1154
|
-
* @param value - The value to clamp.
|
|
1155
|
-
* @param min - The lower bound (inclusive).
|
|
1156
|
-
* @param max - The upper bound (inclusive).
|
|
1157
|
-
* @example
|
|
1158
|
-
* ops.clamp(500, 1000, 2000) // ArbitraryNumber (1000) - below min, returns min
|
|
1159
|
-
*/
|
|
1160
|
-
static clamp(value: ArbitraryNumberish, min: ArbitraryNumberish, max: ArbitraryNumberish): ArbitraryNumber;
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
1113
|
/**
|
|
1164
1114
|
* Domain-level helpers for common game and simulation patterns.
|
|
1165
1115
|
*
|
|
1166
|
-
*
|
|
1167
|
-
* mixed input (`number | ArbitraryNumber`) via
|
|
1168
|
-
* {@link ArbitraryNumberOps.from} so they work at system boundaries
|
|
1169
|
-
* where you may receive raw numbers.
|
|
1170
|
-
*
|
|
1116
|
+
* Accepts mixed input (`number | ArbitraryNumber`) via `ArbitraryNumber.from`.
|
|
1171
1117
|
* For hot-path code, use `ArbitraryNumber` methods directly.
|
|
1172
1118
|
*/
|
|
1173
1119
|
declare class ArbitraryNumberHelpers {
|
|
@@ -1175,9 +1121,6 @@ declare class ArbitraryNumberHelpers {
|
|
|
1175
1121
|
/**
|
|
1176
1122
|
* Returns `true` when `value >= threshold`.
|
|
1177
1123
|
*
|
|
1178
|
-
* @param value - The value to test.
|
|
1179
|
-
* @param threshold - The minimum required value.
|
|
1180
|
-
* @returns `true` when `value >= threshold`.
|
|
1181
1124
|
* @example
|
|
1182
1125
|
* ArbitraryNumberHelpers.meetsOrExceeds(gold, upgradeCost)
|
|
1183
1126
|
*/
|
|
@@ -1187,9 +1130,6 @@ declare class ArbitraryNumberHelpers {
|
|
|
1187
1130
|
*
|
|
1188
1131
|
* Equivalent to `floor(total / step)`.
|
|
1189
1132
|
*
|
|
1190
|
-
* @param total - The total available amount.
|
|
1191
|
-
* @param step - The cost or size of one unit. Must be greater than zero.
|
|
1192
|
-
* @returns The number of whole units that fit, as an `ArbitraryNumber`.
|
|
1193
1133
|
* @throws `"step must be greater than zero"` when `step <= 0`.
|
|
1194
1134
|
* @example
|
|
1195
1135
|
* const canBuy = ArbitraryNumberHelpers.wholeMultipleCount(gold, upgradeCost);
|
|
@@ -1198,14 +1138,10 @@ declare class ArbitraryNumberHelpers {
|
|
|
1198
1138
|
/**
|
|
1199
1139
|
* Returns `value - delta`, clamped to a minimum of `floor` (default `0`).
|
|
1200
1140
|
*
|
|
1201
|
-
* @param value - The starting value.
|
|
1202
|
-
* @param delta - The amount to subtract.
|
|
1203
|
-
* @param floor - The minimum result. Defaults to `ArbitraryNumber.Zero`.
|
|
1204
|
-
* @returns `max(value - delta, floor)`.
|
|
1205
1141
|
* @example
|
|
1206
1142
|
* health = ArbitraryNumberHelpers.subtractWithFloor(health, damage);
|
|
1207
1143
|
*/
|
|
1208
1144
|
static subtractWithFloor(value: ArbitraryNumberish, delta: ArbitraryNumberish, floor?: ArbitraryNumberish): ArbitraryNumber;
|
|
1209
1145
|
}
|
|
1210
1146
|
|
|
1211
|
-
export { AlphabetNotation, type AlphabetNotationOptions,
|
|
1147
|
+
export { AlphabetNotation, type AlphabetNotationOptions, AnFormula, type AnFunction, ArbitraryNumber, type ArbitraryNumberDefaults, ArbitraryNumberDomainError, ArbitraryNumberError, ArbitraryNumberGuard, ArbitraryNumberHelpers, ArbitraryNumberInputError, type ArbitraryNumberJson, ArbitraryNumberMutationError, type ArbitraryNumberish, CLASSIC_UNITS, COMPACT_UNITS, FrozenArbitraryNumber, type Maybe, type Mod3, type NotationPlugin, type Nullable, ScientificNotation, type Signum, SuffixNotationBase, type SuffixNotationPlugin, type SuffixNotationPluginOptions, type SuffixProvider, type Unit, type UnitArray, UnitNotation, type UnitNotationOptions, alphabetSuffix, an, formula, ArbitraryNumberGuard as guard, ArbitraryNumberHelpers as helpers, letterNotation, scientificNotation, unitNotation };
|