@helpers4/number 2.0.2 → 2.0.4

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/llms.txt CHANGED
@@ -1,7 +1,7 @@
1
1
  # @helpers4/number
2
2
 
3
3
  > Tree-shakable TypeScript utility functions for the `number` domain.
4
- > Package: `@helpers4/number` — Version: 2.0.2
4
+ > Package: `@helpers4/number` — Version: 2.0.4
5
5
  > License: LGPL-3.0-or-later
6
6
 
7
7
  ## Installation
@@ -15,7 +15,7 @@ pnpm add @helpers4/number
15
15
  ## Usage
16
16
 
17
17
  ```typescript
18
- import { clamp, correctFloat, formatCompact, ... } from '@helpers4/number';
18
+ import { clamp, correctFloat, extractNumber, ... } from '@helpers4/number';
19
19
  ```
20
20
 
21
21
  ## Functions
@@ -24,15 +24,18 @@ import { clamp, correctFloat, formatCompact, ... } from '@helpers4/number';
24
24
  |---|---|
25
25
  | `clamp` | Clamps a number between min and max values |
26
26
  | `correctFloat` | Corrects floating-point arithmetic errors by rounding to a given number of significant digits. Usefu |
27
+ | `extractNumber` | Extracts the first number embedded anywhere in a string, or passes through a `number`. Unlike a pla |
27
28
  | `formatCompact` | Formats a number using compact notation (e.g. `1_500_000 → "1.5M"`). Thin wrapper over `Intl.Number |
28
29
  | `formatSize` | Format a byte count into a human-readable string with the appropriate unit. Each unit is 1024 of th |
29
30
  | `inRange` | Checks whether a number falls within `[min, max]` (both inclusive by default). |
31
+ | `isEven` | Checks if a value is an even integer. Returns `false` for non-numbers, non-integers, `NaN`, `Infini |
32
+ | `isNegative` | Checks if a value is a number less than 0. Returns `false` for `NaN`, `0`, positive numbers, and no |
33
+ | `isOdd` | Checks if a value is an odd integer. Returns `false` for non-numbers, non-integers, `NaN`, `Infinit |
34
+ | `isPositive` | Checks if a value is a number greater than 0. Returns `false` for `NaN`, `0`, negative numbers, and |
30
35
  | `lerp` | Linearly interpolates between `start` and `end` by the factor `t`. - `t = 0` returns `start`. - `t |
31
- | `mean` | Calculates the arithmetic mean (average) of an array of numbers. Returns `NaN` for an empty array. |
32
36
  | `randomBetween` | Generates a random number between min and max (inclusive) |
33
37
  | `randomIntBetween` | Generates a random integer between min and max (inclusive) |
34
38
  | `roundTo` | Rounds a number to specified decimal places |
35
- | `sum` | Calculates the sum of an array of numbers. |
36
39
 
37
40
  ---
38
41
 
@@ -83,6 +86,10 @@ Note: for values whose integer part already consumes 14 or more digits
83
86
  digits and will silently truncate them. Increase `precision` if you
84
87
  need to correct drift in very large numbers.
85
88
 
89
+ Note: IEEE-754 doubles carry at most ~17 significant decimal digits.
90
+ Precision values above 17 pad with digits that reflect the underlying
91
+ binary representation rather than correcting drift.
92
+
86
93
  ```typescript
87
94
  import { correctFloat } from '@helpers4/number';
88
95
 
@@ -92,7 +99,9 @@ correctFloat(value: number, precision: number): number
92
99
  **Parameters:**
93
100
 
94
101
  - `value: number` — The floating-point value to correct
95
- - `precision: number` (default: `14`) — Integer number of significant digits (default: 14)
102
+ - `precision: number` (default: `14`) — Integer number of significant digits between 1 and 100
103
+ (default: 14). Values above 17 are valid but expose binary noise beyond
104
+ IEEE-754's meaningful range.
96
105
 
97
106
  **Returns:** `number` — The corrected value
98
107
 
@@ -118,6 +127,53 @@ correctFloat(1.23456789, 6) // => 1.23457
118
127
 
119
128
  ---
120
129
 
130
+ ### `extractNumber`
131
+
132
+ Extracts the first number embedded anywhere in a string, or passes through a `number`.
133
+
134
+ Unlike a plain `parseFloat`/`parseInt`, the number does not need to be at the start of
135
+ the string: digits are searched for anywhere, so leading/trailing text (units, labels, ...)
136
+ is ignored. A `-` before the digits and a scientific-notation suffix (`e`/`E`) are
137
+ disambiguated with ExtractNumberOptions.sign and ExtractNumberOptions.exponent.
138
+
139
+ Returns `undefined` if no number can be found.
140
+
141
+ ```typescript
142
+ import { extractNumber } from '@helpers4/number';
143
+
144
+ extractNumber(value: unknown, options: ExtractNumberOptions): number | undefined
145
+ ```
146
+
147
+ **Parameters:**
148
+
149
+ - `value: unknown` — The value to extract a number from
150
+ - `options: ExtractNumberOptions` (default: `{}`) — Options controlling sign and exponent disambiguation
151
+
152
+ **Returns:** `number | undefined` — The extracted number, or `undefined` if none was found
153
+
154
+ **Examples:**
155
+
156
+ *extractNumber*
157
+
158
+ ```typescript
159
+ ```ts
160
+ extractNumber('16.5px') // => 16.5
161
+ extractNumber('.5rem') // => 0.5 (leading-dot decimal)
162
+ extractNumber('-.5') // => -0.5 (leading-dot with sign)
163
+ extractNumber('Wafer 10') // => 10
164
+ extractNumber('xxx-111') // => 111 ('-' glued to text → separator)
165
+ extractNumber('xxx -111') // => -111 ('-' preceded by a space → sign)
166
+ extractNumber('x-.5') // => 0.5 ('-' glued to 'x' → separator; leading-dot decimal follows)
167
+ extractNumber('-111') // => -111 ('-' at the start of the string → sign)
168
+ extractNumber('1e5 mol') // => 100000
169
+ extractNumber('1e5kg') // => 1 ('e5' glued to text → mantissa only)
170
+ extractNumber('no number') // => undefined
171
+ extractNumber(42) // => 42
172
+ ```
173
+ ```
174
+
175
+ ---
176
+
121
177
  ### `formatCompact`
122
178
 
123
179
  Formats a number using compact notation (e.g. `1_500_000 → "1.5M"`).
@@ -239,80 +295,204 @@ inRange(10, 1, 10, { inclusive: 'none' }) // => false
239
295
 
240
296
  ---
241
297
 
242
- ### `lerp`
298
+ ### `isEven`
243
299
 
244
- Linearly interpolates between `start` and `end` by the factor `t`.
300
+ Checks if a value is an even integer.
245
301
 
246
- - `t = 0` returns `start`.
247
- - `t = 1` returns `end`.
248
- - Values of `t` outside `[0, 1]` extrapolate beyond the range.
302
+ Returns `false` for non-numbers, non-integers, `NaN`, `Infinity`, and odd integers.
249
303
 
250
304
  ```typescript
251
- import { lerp } from '@helpers4/number';
305
+ import { isEven } from '@helpers4/number';
252
306
 
253
- lerp(start: number, end: number, t: number): number
307
+ isEven(value: unknown): value is number
254
308
  ```
255
309
 
256
310
  **Parameters:**
257
311
 
258
- - `start: number` — The start value.
259
- - `end: number` — The end value.
260
- - `t: number` — The interpolation factor.
312
+ - `value: unknown` — The value to check
261
313
 
262
- **Returns:** `number` — The interpolated value.
314
+ **Returns:** `value is number` — `true` if value is an integer divisible by 2
263
315
 
264
316
  **Examples:**
265
317
 
266
- *Interpolate between two values*
318
+ *Check if a number is even*
267
319
 
268
- Returns the value between start and end at position t (0 = start, 1 = end).
320
+ Returns true for integers divisible by 2, false otherwise.
269
321
 
270
322
  ```typescript
271
- lerp(0, 100, 0) // => 0
272
- lerp(0, 100, 0.5) // => 50
273
- lerp(0, 100, 1) // => 100
323
+ isEven(4) // => true
324
+ isEven(0) // => true
325
+ isEven(3) // => false
326
+ isEven(1.5) // => false (not an integer)
274
327
  ```
275
328
 
276
- *Animate a colour channel*
329
+ *Filter even numbers from an array*
277
330
 
278
- t outside [0, 1] extrapolates beyond the range.
331
+ Use as a predicate in .filter() to extract even integers.
279
332
 
280
333
  ```typescript
281
- lerp(0, 255, 0.5) // => 127.5
282
- lerp(0, 10, 2) // => 20 (extrapolation)
334
+ const nums = [1, 2, 3, 4, 5, 6];
335
+ nums.filter(isEven)
336
+ // => [2, 4, 6]
337
+ ```
338
+
339
+ ---
340
+
341
+ ### `isNegative`
342
+
343
+ Checks if a value is a number less than 0.
344
+
345
+ Returns `false` for `NaN`, `0`, positive numbers, and non-number types.
346
+
347
+ ```typescript
348
+ import { isNegative } from '@helpers4/number';
349
+
350
+ isNegative(value: unknown): value is number
351
+ ```
352
+
353
+ **Parameters:**
354
+
355
+ - `value: unknown` — The value to check
356
+
357
+ **Returns:** `value is number` — True if value is a negative number
358
+
359
+ **Examples:**
360
+
361
+ *isNegative*
362
+
363
+ ```typescript
364
+ ```ts
365
+ isNegative(-1) // => true
366
+ isNegative(-0.5) // => true
367
+ isNegative(-Infinity) // => true
368
+ isNegative(0) // => false
369
+ isNegative(1) // => false
370
+ isNegative(NaN) // => false
371
+ ```
372
+ ```
373
+
374
+ ---
375
+
376
+ ### `isOdd`
377
+
378
+ Checks if a value is an odd integer.
379
+
380
+ Returns `false` for non-numbers, non-integers, `NaN`, `Infinity`, and even integers.
381
+
382
+ ```typescript
383
+ import { isOdd } from '@helpers4/number';
384
+
385
+ isOdd(value: unknown): value is number
386
+ ```
387
+
388
+ **Parameters:**
389
+
390
+ - `value: unknown` — The value to check
391
+
392
+ **Returns:** `value is number` — `true` if value is an integer not divisible by 2
393
+
394
+ **Examples:**
395
+
396
+ *Check if a number is odd*
397
+
398
+ Returns true for integers not divisible by 2, false otherwise.
399
+
400
+ ```typescript
401
+ isOdd(3) // => true
402
+ isOdd(1) // => true
403
+ isOdd(2) // => false
404
+ isOdd(0) // => false
405
+ isOdd(1.5) // => false (not an integer)
406
+ ```
407
+
408
+ *Filter odd numbers from an array*
409
+
410
+ Use as a predicate in .filter() to extract odd integers.
411
+
412
+ ```typescript
413
+ const nums = [1, 2, 3, 4, 5, 6];
414
+ nums.filter(isOdd)
415
+ // => [1, 3, 5]
283
416
  ```
284
417
 
285
418
  ---
286
419
 
287
- ### `mean`
420
+ ### `isPositive`
288
421
 
289
- Calculates the arithmetic mean (average) of an array of numbers.
290
- Returns `NaN` for an empty array.
422
+ Checks if a value is a number greater than 0.
291
423
 
292
- Pairs with sum for aggregate operations.
424
+ Returns `false` for `NaN`, `0`, negative numbers, and non-number types.
293
425
 
294
426
  ```typescript
295
- import { mean } from '@helpers4/number';
427
+ import { isPositive } from '@helpers4/number';
296
428
 
297
- mean(array: readonly number[]): number
429
+ isPositive(value: unknown): value is number
298
430
  ```
299
431
 
300
432
  **Parameters:**
301
433
 
302
- - `array: readonly number[]` — The array of numbers to average
434
+ - `value: unknown` — The value to check
435
+
436
+ **Returns:** `value is number` — True if value is a positive number
437
+
438
+ **Examples:**
439
+
440
+ *isPositive*
441
+
442
+ ```typescript
443
+ ```ts
444
+ isPositive(42) // => true
445
+ isPositive(0.1) // => true
446
+ isPositive(Infinity) // => true
447
+ isPositive(0) // => false
448
+ isPositive(-1) // => false
449
+ isPositive(NaN) // => false
450
+ ```
451
+ ```
452
+
453
+ ---
454
+
455
+ ### `lerp`
456
+
457
+ Linearly interpolates between `start` and `end` by the factor `t`.
458
+
459
+ - `t = 0` returns `start`.
460
+ - `t = 1` returns `end`.
461
+ - Values of `t` outside `[0, 1]` extrapolate beyond the range.
462
+
463
+ ```typescript
464
+ import { lerp } from '@helpers4/number';
465
+
466
+ lerp(start: number, end: number, t: number): number
467
+ ```
468
+
469
+ **Parameters:**
470
+
471
+ - `start: number` — The start value.
472
+ - `end: number` — The end value.
473
+ - `t: number` — The interpolation factor.
303
474
 
304
- **Returns:** `number` — The arithmetic mean, or `NaN` if the array is empty
475
+ **Returns:** `number` — The interpolated value.
305
476
 
306
477
  **Examples:**
307
478
 
308
- *Average a list of numbers*
479
+ *Interpolate between two values*
480
+
481
+ Returns the value between start and end at position t (0 = start, 1 = end).
482
+
483
+ ```typescript
484
+ lerp(0, 100, 0) // => 0
485
+ lerp(0, 100, 0.5) // => 50
486
+ lerp(0, 100, 1) // => 100
487
+ ```
488
+
489
+ *Animate a colour channel*
309
490
 
310
- Returns the arithmetic mean of the array; NaN for empty arrays.
491
+ t outside [0, 1] extrapolates beyond the range.
311
492
 
312
493
  ```typescript
313
- mean([1, 2, 3, 4]) // => 2.5
314
- mean([10, 20, 30]) // => 20
315
- mean([]) // => NaN
494
+ lerp(0, 255, 0.5) // => 127.5
495
+ lerp(0, 10, 2) // => 20 (extrapolation)
316
496
  ```
317
497
 
318
498
  ---
@@ -413,41 +593,3 @@ roundTo(3.7, 0)
413
593
  ```
414
594
 
415
595
  ---
416
-
417
- ### `sum`
418
-
419
- Calculates the sum of an array of numbers.
420
-
421
- ```typescript
422
- import { sum } from '@helpers4/number';
423
-
424
- sum(array: readonly number[]): number
425
- ```
426
-
427
- **Parameters:**
428
-
429
- - `array: readonly number[]` — The array of numbers to sum
430
-
431
- **Returns:** `number` — The sum of all values
432
-
433
- **Examples:**
434
-
435
- *Sum numbers*
436
-
437
- Calculates the sum of an array of numbers.
438
-
439
- ```typescript
440
- sum([1, 2, 3, 4])
441
- // => 10
442
- ```
443
-
444
- *Sum with negative numbers*
445
-
446
- Handles negative numbers correctly.
447
-
448
- ```typescript
449
- sum([10, -3, 5, -2])
450
- // => 10
451
- ```
452
-
453
- ---