@oazmi/superbuild 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/_dnt.shims.d.ts +2 -0
- package/esm/_dnt.shims.d.ts.map +1 -0
- package/esm/_dnt.shims.js +57 -0
- package/esm/deps/jsr.io/@oazmi/esbuild-types/0.28.0/src/mod.d.ts +598 -0
- package/esm/deps/jsr.io/@oazmi/esbuild-types/0.28.0/src/mod.d.ts.map +1 -0
- package/esm/deps/jsr.io/@oazmi/esbuild-types/0.28.0/src/mod.js +1 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/alias.d.ts +617 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/alias.d.ts.map +1 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/alias.js +671 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/array1d.d.ts +487 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/array1d.d.ts.map +1 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/array1d.js +536 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/array2d.d.ts +266 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/array2d.d.ts.map +1 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/array2d.js +318 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/binder.d.ts +368 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/binder.d.ts.map +1 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/binder.js +380 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/crossenv.d.ts +711 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/crossenv.d.ts.map +1 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/crossenv.js +1173 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/cryptoman.d.ts +171 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/cryptoman.d.ts.map +1 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/cryptoman.js +308 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/deps.d.ts +10 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/deps.d.ts.map +1 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/deps.js +10 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/eightpack.d.ts +168 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/eightpack.d.ts.map +1 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/eightpack.js +236 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/eightpack_varint.d.ts +90 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/eightpack_varint.d.ts.map +1 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/eightpack_varint.js +237 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/numericarray.d.ts +213 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/numericarray.d.ts.map +1 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/numericarray.js +363 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/numericmethods.d.ts +233 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/numericmethods.d.ts.map +1 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/numericmethods.js +256 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/pathman.d.ts +1436 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/pathman.d.ts.map +1 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/pathman.js +1730 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/promiseman.d.ts +647 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/promiseman.d.ts.map +1 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/promiseman.js +762 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/stringman.d.ts +538 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/stringman.d.ts.map +1 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/stringman.js +626 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/struct.d.ts +734 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/struct.d.ts.map +1 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/struct.js +764 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/typedbuffer.d.ts +137 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/typedbuffer.d.ts.map +1 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/typedbuffer.js +234 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/typedefs.d.ts +391 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/typedefs.d.ts.map +1 -0
- package/esm/deps/jsr.io/@oazmi/kitchensink/0.10.0/src/typedefs.js +8 -0
- package/esm/deps.d.ts +56 -0
- package/esm/deps.d.ts.map +1 -0
- package/esm/deps.js +37 -0
- package/esm/esbuild/metafile.d.ts +90 -0
- package/esm/esbuild/metafile.d.ts.map +1 -0
- package/esm/esbuild/metafile.js +275 -0
- package/esm/esbuild/native.d.ts +95 -0
- package/esm/esbuild/native.d.ts.map +1 -0
- package/esm/esbuild/native.js +127 -0
- package/esm/esbuild/outputfile.d.ts +86 -0
- package/esm/esbuild/outputfile.d.ts.map +1 -0
- package/esm/esbuild/outputfile.js +221 -0
- package/esm/esbuild/strongtypes.d.ts +90 -0
- package/esm/esbuild/strongtypes.d.ts.map +1 -0
- package/esm/esbuild/strongtypes.js +8 -0
- package/esm/esbuild/typedefs.d.ts +121 -0
- package/esm/esbuild/typedefs.d.ts.map +1 -0
- package/esm/esbuild/typedefs.js +55 -0
- package/esm/esbuild/weaktypes.d.ts +46 -0
- package/esm/esbuild/weaktypes.d.ts.map +1 -0
- package/esm/esbuild/weaktypes.js +8 -0
- package/esm/funcdefs.d.ts +89 -0
- package/esm/funcdefs.d.ts.map +1 -0
- package/esm/funcdefs.js +145 -0
- package/esm/mod.d.ts +4 -0
- package/esm/mod.d.ts.map +1 -0
- package/esm/mod.js +2 -0
- package/esm/package.json +3 -0
- package/esm/plugins/emissions_driver.d.ts +33 -0
- package/esm/plugins/emissions_driver.d.ts.map +1 -0
- package/esm/plugins/emissions_driver.js +260 -0
- package/esm/plugins/long_build.d.ts +138 -0
- package/esm/plugins/long_build.d.ts.map +1 -0
- package/esm/plugins/long_build.js +288 -0
- package/esm/plugins/native_replica.d.ts +48 -0
- package/esm/plugins/native_replica.d.ts.map +1 -0
- package/esm/plugins/native_replica.js +122 -0
- package/esm/super/build.d.ts +53 -0
- package/esm/super/build.d.ts.map +1 -0
- package/esm/super/build.js +39 -0
- package/esm/super/build_context.d.ts +83 -0
- package/esm/super/build_context.d.ts.map +1 -0
- package/esm/super/build_context.js +124 -0
- package/esm/super/mod.d.ts +12 -0
- package/esm/super/mod.d.ts.map +1 -0
- package/esm/super/mod.js +9 -0
- package/esm/super/plugin.d.ts +23 -0
- package/esm/super/plugin.d.ts.map +1 -0
- package/esm/super/plugin.js +31 -0
- package/esm/super/plugin_build.d.ts +38 -0
- package/esm/super/plugin_build.d.ts.map +1 -0
- package/esm/super/plugin_build.js +198 -0
- package/esm/super/typedefs.d.ts +323 -0
- package/esm/super/typedefs.d.ts.map +1 -0
- package/esm/super/typedefs.js +10 -0
- package/esm/typedefs.d.ts +21 -0
- package/esm/typedefs.d.ts.map +1 -0
- package/esm/typedefs.js +5 -0
- package/license.md +37 -0
- package/package.json +88 -0
- package/readme.md +181 -0
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/** utility functions for common number manipulation functions.
|
|
2
|
+
*
|
|
3
|
+
* these functions go nicely with the {@link "mapper"} and {@link "lambdacalc"} submodules.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import { math_round, number_MAX_VALUE } from "./alias.js";
|
|
8
|
+
/** clamp a `number` to inclusive `min` and `max` intervals.
|
|
9
|
+
*
|
|
10
|
+
* you can also provide a type alias for the output interval `OutInterval` number through the use of the generic parameter.
|
|
11
|
+
*
|
|
12
|
+
* @param value value to clamp
|
|
13
|
+
* @param min inclusive minimum of the interval
|
|
14
|
+
* @param max inclusive maximum of the interval
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { assertEquals } from "jsr:@std/assert"
|
|
19
|
+
*
|
|
20
|
+
* assertEquals(clamp(-5, -1, 10), -1)
|
|
21
|
+
* assertEquals(clamp(5, -1, 10), 5)
|
|
22
|
+
* assertEquals(clamp(15, -1, 10), 10)
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export const clamp = (value, min = -number_MAX_VALUE, max = number_MAX_VALUE) => (value < min ? min : value > max ? max : value);
|
|
26
|
+
/** get the mathematical modulo: `value` **mod** `mod`.
|
|
27
|
+
*
|
|
28
|
+
* **modulo** is different from javascript's `%` **remainder** operator in that the **modulo** operation always returns a positive number.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* import { assertEquals } from "jsr:@std/assert"
|
|
33
|
+
*
|
|
34
|
+
* assertEquals(modulo( 5, 3), 2)
|
|
35
|
+
* assertEquals(modulo(-5, 3), 1)
|
|
36
|
+
* assertEquals(modulo(-4, 3), 2)
|
|
37
|
+
* assertEquals(modulo(-3, 3), 0)
|
|
38
|
+
* assertEquals( 5 % 3, 2)
|
|
39
|
+
* assertEquals(-5 % 3, -2)
|
|
40
|
+
* assertEquals(-4 % 3, -1)
|
|
41
|
+
* assertEquals(-3 % 3, -0)
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export const modulo = (value, mod) => (((value % mod) + mod) % mod);
|
|
45
|
+
/** get the linearly interpolated value between two scalar points `x0` and `x1`, decided by unit interval time `t`.
|
|
46
|
+
*
|
|
47
|
+
* in other words:
|
|
48
|
+
* - `lerp(x0, x1, 0.0) === x0`
|
|
49
|
+
* - `lerp(x0, x1, 1.0) === x1`
|
|
50
|
+
* - `x0 < lerp(x0, x1, t > 0.0 && t < 1.0) < x1`
|
|
51
|
+
*
|
|
52
|
+
* > [!note]
|
|
53
|
+
* > this lerp function does not clamp the time parameter `t` to the closed {@link UnitInterval} `[0.0, 1.0]`.
|
|
54
|
+
* > to ensure clamping of `t` to the unit interval, use the {@link lerpClamped} function.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* import { assertEquals } from "jsr:@std/assert"
|
|
59
|
+
*
|
|
60
|
+
* assertEquals(lerp( 0, 100, 0.5), 50)
|
|
61
|
+
* assertEquals(lerp(50, 100, 0.5), 75)
|
|
62
|
+
* assertEquals(lerp(50, 100, 0.0), 50)
|
|
63
|
+
* assertEquals(lerp(50, 100, 1.0), 100)
|
|
64
|
+
* assertEquals(lerp(50, 100, 1.5), 125)
|
|
65
|
+
* assertEquals(lerp(50, 100, -0.5), 25)
|
|
66
|
+
* assertEquals(lerp(50, 100, -1.0), 0)
|
|
67
|
+
* assertEquals(lerp(50, 100, -2.5), -75)
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export const lerp = (x0, x1, t) => (t * (x1 - x0) + x0);
|
|
71
|
+
/** same as {@link lerp}, except the time `t` is Clamped to the closed {@link UnitInterval} `[0.0, 1.0]`. */
|
|
72
|
+
export const lerpClamped = (x0, x1, t) => ((t < 0 ? 0 : t > 1 ? 1 : t) * (x1 - x0) + x0);
|
|
73
|
+
/** get the {@link lerp} interpolation of the `i`th dimension of two array vector points `v0` and `v1`, at time `t`.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* import { assertEquals } from "jsr:@std/assert"
|
|
78
|
+
*
|
|
79
|
+
* assertEquals(lerpi([ 0, 40], [100, 80], 0.5, 0), 50)
|
|
80
|
+
* assertEquals(lerpi([ 0, 40], [100, 80], 0.5, 1), 60)
|
|
81
|
+
* assertEquals(lerpi([50, 40], [100, 80], 0.5, 0), 75)
|
|
82
|
+
* assertEquals(lerpi([50, 40], [100, 80], 0.0, 0), 50)
|
|
83
|
+
* assertEquals(lerpi([50, 40], [100, 80], 1.0, 0), 100)
|
|
84
|
+
* assertEquals(lerpi([50, 40], [100, 80], 1.5, 0), 125)
|
|
85
|
+
* assertEquals(lerpi([50, 40], [100, 80], -0.5, 0), 25)
|
|
86
|
+
* assertEquals(lerpi([50, 40], [100, 80], -1.0, 0), 0)
|
|
87
|
+
* assertEquals(lerpi([50, 40], [100, 80], -2.5, 0), -75)
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export const lerpi = (v0, v1, t, i) => (t * (v1[i] - v0[i]) + v0[i]);
|
|
91
|
+
/** get the {@link lerpClamped} interpolation of the `i`th dimension of two array vector points `v0` and `v1`, at time `t`. */
|
|
92
|
+
export const lerpiClamped = (v0, v1, t, i) => (t < 0 ? 0 : t > 1 ? 1 : t) * (v1[i] - v0[i]) + v0[i];
|
|
93
|
+
/** get the {@link lerp} interpolation vector between two array vector points `v0` and `v1`, at time `t`.
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```ts
|
|
97
|
+
* import { assertEquals } from "jsr:@std/assert"
|
|
98
|
+
*
|
|
99
|
+
* assertEquals(lerpv([ 0, 40], [100, 80], 0.5), [ 50, 60])
|
|
100
|
+
* assertEquals(lerpv([50, 0], [100, 80], 0.5), [ 75, 40])
|
|
101
|
+
* assertEquals(lerpv([50, 40], [100, 80], 0.0), [ 50, 40])
|
|
102
|
+
* assertEquals(lerpv([50, 40], [100, 80], 1.0), [100, 80])
|
|
103
|
+
* assertEquals(lerpv([50, 40], [100, 80], 1.5), [125, 100])
|
|
104
|
+
* assertEquals(lerpv([50, 40], [100, 80], -0.5), [ 25, 20])
|
|
105
|
+
* assertEquals(lerpv([50, 40], [100, 80], -1.0), [ 0, 0])
|
|
106
|
+
* assertEquals(lerpv([50, 40], [100, 80], -2.5), [-75, -60])
|
|
107
|
+
* assertEquals(lerpv(
|
|
108
|
+
* [ 0, 10, 100, 1000],
|
|
109
|
+
* [1000, 100, 10, 0],
|
|
110
|
+
* 0.25,
|
|
111
|
+
* ), [250, 32.5, 77.5, 750])
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
export const lerpv = (v0, v1, t) => {
|
|
115
|
+
const len = v0.length, v = Array(len).fill(0);
|
|
116
|
+
for (let i = 0; i < len; i++) {
|
|
117
|
+
v[i] = t * (v1[i] - v0[i]) + v0[i];
|
|
118
|
+
}
|
|
119
|
+
return v;
|
|
120
|
+
};
|
|
121
|
+
/** get the {@link lerpClamped} interpolation vector between two array vector points `v0` and `v1`, at time `t`. */
|
|
122
|
+
export const lerpvClamped = (v0, v1, t) => lerpv(v0, v1, t < 0 ? 0 : t > 1 ? 1 : t);
|
|
123
|
+
/** get the inverse of the interpolation {@link lerp}`(x0, x1, t)`, which is to say:
|
|
124
|
+
* find the {@link UnitInterval} parameter `t`, given a scalar number `x` in the closed interval `[x0, x1]`.
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```ts
|
|
128
|
+
* import { assertEquals } from "jsr:@std/assert"
|
|
129
|
+
*
|
|
130
|
+
* assertEquals(invlerp( 0, 100, 50), 0.5)
|
|
131
|
+
* assertEquals(invlerp(50, 100, 75), 0.5)
|
|
132
|
+
* assertEquals(invlerp(50, 100, 50), 0.0)
|
|
133
|
+
* assertEquals(invlerp(50, 100, 100), 1.0)
|
|
134
|
+
* assertEquals(invlerp(50, 100, 125), 1.5)
|
|
135
|
+
* assertEquals(invlerp(50, 100, 25), -0.5)
|
|
136
|
+
* assertEquals(invlerp(50, 100, 0), -1.0)
|
|
137
|
+
* assertEquals(invlerp(50, 100, -75), -2.5)
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
export const invlerp = (x0, x1, x) => ((x - x0) / (x1 - x0));
|
|
141
|
+
/** same as {@link invlerp}, except that we force clamp the output {@link UnitInterval} `t` to the closed interval `[0, 1]`. */
|
|
142
|
+
export const invlerpClamped = (x0, x1, x) => {
|
|
143
|
+
const t = (x - x0) / (x1 - x0);
|
|
144
|
+
return t < 0 ? 0 : t > 1 ? 1 : t;
|
|
145
|
+
};
|
|
146
|
+
/** get the {@link invlerp} (inverse interpolation) of the `i`th dimension of two vector point intervals `v0` and `v1`, at vector position `v`. */
|
|
147
|
+
export const invlerpi = (v0, v1, v, i) => (v[i] - v0[i]) / (v1[i] - v0[i]);
|
|
148
|
+
/** get the {@link invlerpClamped} of the `i`th dimension of two array vector point intervals `v0` and `v1`, at vector position `v`. */
|
|
149
|
+
export const invlerpiClamped = (v0, v1, v, i) => {
|
|
150
|
+
const t = (v[i] - v0[i]) / (v1[i] - v0[i]);
|
|
151
|
+
return t < 0 ? 0 : t > 1 ? 1 : t;
|
|
152
|
+
};
|
|
153
|
+
/** `limp` is a made up abbreviation for _linear interval map_, which linearly maps:
|
|
154
|
+
* - a scalar value `x0`, that's in a
|
|
155
|
+
* - scalar interval `u0: [min: number, max: number]` to
|
|
156
|
+
* - a scalar output return value `x1`, that's in the
|
|
157
|
+
* - scalar interval `u1: [min: number, max: number]`
|
|
158
|
+
*
|
|
159
|
+
* the math equation is simply `x1 = u1[0] + (x - u0[0]) * (u1[1] - u1[0]) / (u0[1] - u0[0])`.
|
|
160
|
+
* which is basically doing inverse_lerp on `x0` to find `t`, then applying lerp onto interval `u1` with the found `t`.
|
|
161
|
+
*
|
|
162
|
+
* you may think of this function as a means for finding the "y-coordinate" (`x1`) of a point at the "x-coordinate" `x0`,
|
|
163
|
+
* that is between two connected line segment points `(u0[0], u1[0])` and `(u0[1], u1[1])`.
|
|
164
|
+
*/
|
|
165
|
+
export const limp = (u0, u1, x0) => (u1[0] + (x0 - u0[0]) * (u1[1] - u1[0]) / (u0[1] - u0[0]));
|
|
166
|
+
/** same as {@link limp}, except the output `x1` is force clamped to the interval `u1`. */
|
|
167
|
+
export const limpClamped = (u0, u1, x0) => {
|
|
168
|
+
const t = (x0 - u0[0]) / (u0[1] - u0[0]);
|
|
169
|
+
return (t < 0 ? 0 : t > 1 ? 1 : t) * (u1[1] - u1[0]) + u1[0];
|
|
170
|
+
};
|
|
171
|
+
/** sum up an array of numbers.
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```ts
|
|
175
|
+
* import { assertEquals } from "jsr:@std/assert"
|
|
176
|
+
*
|
|
177
|
+
* assertEquals(sum([0, 1, 2, 3, 4]), 10)
|
|
178
|
+
* assertEquals(sum([-11, 7, 5, -8]), -7)
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
export const sum = (values) => {
|
|
182
|
+
let total = 0, len = values.length;
|
|
183
|
+
for (let i = 0; i < len; i++) {
|
|
184
|
+
total += values[i];
|
|
185
|
+
}
|
|
186
|
+
return total;
|
|
187
|
+
};
|
|
188
|
+
/** get the minimum between two numbers.
|
|
189
|
+
*
|
|
190
|
+
* this function is faster than `Math.min` as it uses the ternary conditional operator, which makes it highly JIT optimized.
|
|
191
|
+
*/
|
|
192
|
+
export const min = (v0, v1) => (v0 < v1 ? v0 : v1);
|
|
193
|
+
/** get the maximum between two numbers.
|
|
194
|
+
*
|
|
195
|
+
* this function is faster than `Math.max` as it uses the ternary conditional operator, which makes it highly JIT optimized.
|
|
196
|
+
*/
|
|
197
|
+
export const max = (v0, v1) => (v0 > v1 ? v0 : v1);
|
|
198
|
+
/** get the sign of a number. you'll get a `1` for positive numbers (or zero), and `-1` otherwise.
|
|
199
|
+
*
|
|
200
|
+
* this function is faster than `Math.sign` as it uses the ternary conditional operator, which makes it highly JIT optimized.
|
|
201
|
+
*/
|
|
202
|
+
export const sign = (value) => (value >= 0 ? 1 : -1);
|
|
203
|
+
/** get the absolute positive value of a number.
|
|
204
|
+
*
|
|
205
|
+
* this function is faster than `Math.abs` as it uses the ternary conditional operator, which makes it highly JIT optimized.
|
|
206
|
+
*
|
|
207
|
+
* the reason why we don't call this function `abs` is because one such function already exists in the numericarray submodule ({@link abs}).
|
|
208
|
+
*/
|
|
209
|
+
export const absolute = (value) => ((value >= 0 ? 1 : -1) * value);
|
|
210
|
+
/** round a float number to a certain precision, so that floating floating-point arithmetic inaccuracies can be nullified.
|
|
211
|
+
*
|
|
212
|
+
* the way it works is by multiplying the initial `value` by a large number, so that it is at least a whole number,
|
|
213
|
+
* and then we round it to the closest integer value with `Math.round`,
|
|
214
|
+
* and finally we follow it up with a division by the very same old large number.
|
|
215
|
+
*
|
|
216
|
+
* @param value the floating number to round.
|
|
217
|
+
* @param precision an integer dictating the number of decimal points to which the `value` should be rounded to.
|
|
218
|
+
* you may use negative integer for rounding to `10s`, `100s`, etc..., or use a value of `0` for rounding to nearest integer.
|
|
219
|
+
* also, you would want to the `precision` to be less than the number of decimal digits representable by your js-runtime's floating-point.
|
|
220
|
+
* so for 64-bit runtime (double), the max precision limit is `15`, and for a 32-bit runtime (single), the limit is `7`.
|
|
221
|
+
* picking a precision that is higher than your runtime's limit will result in even worse value rounding than your original `value`.
|
|
222
|
+
* defaults to `9` (i.e. rounds to closest nano-number (10**(-9))).
|
|
223
|
+
* @returns the float number rounded to the given precision.
|
|
224
|
+
*
|
|
225
|
+
* @examples
|
|
226
|
+
* ```ts
|
|
227
|
+
* import { assert } from "jsr:@std/assert"
|
|
228
|
+
*
|
|
229
|
+
* // aliasing our function for brevity
|
|
230
|
+
* const fn = roundFloat
|
|
231
|
+
*
|
|
232
|
+
* // notice that due to floating inaccuracy `0.2 + 0.4` equals to `0.6000000000000001` instead of `0.6`
|
|
233
|
+
* assert((0.2 + 0.4) !== 0.6)
|
|
234
|
+
* assert((0.2 + 0.4) === 0.6000000000000001)
|
|
235
|
+
*
|
|
236
|
+
* // so, it is often desirable to round the resulting number to some precision to negate this slight deviation.
|
|
237
|
+
* assert(fn(0.2 + 0.4) === 0.6)
|
|
238
|
+
*
|
|
239
|
+
* // you can also provide a custom precision with the second parameter
|
|
240
|
+
* assert(fn(123.456789, 2) === 123.46) // rounding to 2 decimal places
|
|
241
|
+
* assert(fn(123.456789, 1) === 123.5) // rounding to 1 decimal places
|
|
242
|
+
* assert(fn(123.456789, 0) === 123) // rounding to 0 decimal places (i.e. closest integer)
|
|
243
|
+
* assert(fn(123.456789, -1) === 120) // rounding to -1 decimal places (i.e. closest 10s)
|
|
244
|
+
* assert(fn(123.456789, -2) === 100) // rounding to -2 decimal places (i.e. closest 100s)
|
|
245
|
+
*
|
|
246
|
+
* // other examples:
|
|
247
|
+
* assert( (0.2 - 0.7) === -0.49999999999999994)
|
|
248
|
+
* assert(fn(0.2 - 0.7) === -0.5)
|
|
249
|
+
* assert( (0.2 * 3.0) === 0.6000000000000001)
|
|
250
|
+
* assert(fn(0.2 * 3.0) === 0.6)
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
export const roundFloat = (value, precision = 9) => {
|
|
254
|
+
const large_number = 10 ** precision;
|
|
255
|
+
return math_round((value * large_number)) / large_number;
|
|
256
|
+
};
|