@flighthq/math 0.3.0 → 0.3.1-next.1041.35b950c

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/constants.d.ts +16 -1
  2. package/dist/constants.d.ts.map +1 -1
  3. package/dist/constants.js +16 -1
  4. package/dist/constants.js.map +1 -1
  5. package/dist/index.d.ts +2 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +1 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/interpolationAdvanced.d.ts.map +1 -1
  10. package/dist/interpolationAdvanced.js +8 -4
  11. package/dist/interpolationAdvanced.js.map +1 -1
  12. package/dist/nextPowerOfTwo.d.ts.map +1 -1
  13. package/dist/nextPowerOfTwo.js +6 -1
  14. package/dist/nextPowerOfTwo.js.map +1 -1
  15. package/dist/numberTheory.d.ts +2 -2
  16. package/dist/numberTheory.d.ts.map +1 -1
  17. package/dist/numberTheory.js +5 -2
  18. package/dist/numberTheory.js.map +1 -1
  19. package/dist/randomDistributions.d.ts +2 -2
  20. package/dist/randomDistributions.d.ts.map +1 -1
  21. package/dist/randomDistributions.js +8 -6
  22. package/dist/randomDistributions.js.map +1 -1
  23. package/dist/randomRange.d.ts +3 -4
  24. package/dist/randomRange.d.ts.map +1 -1
  25. package/dist/randomRange.js +3 -4
  26. package/dist/randomRange.js.map +1 -1
  27. package/dist/statistics.d.ts.map +1 -1
  28. package/dist/statistics.js +101 -13
  29. package/dist/statistics.js.map +1 -1
  30. package/package.json +2 -2
  31. package/src/angle.test.ts +3 -0
  32. package/src/constants.test.ts +32 -1
  33. package/src/hash.test.ts +3 -0
  34. package/src/interpolationAdvanced.test.ts +14 -4
  35. package/src/nextPowerOfTwo.test.ts +11 -0
  36. package/src/numberTheory.test.ts +9 -0
  37. package/src/random.test.ts +7 -0
  38. package/src/randomDistributions.test.ts +88 -0
  39. package/src/randomRange.test.ts +12 -0
  40. package/src/statistics.test.ts +59 -0
@@ -1,4 +1,19 @@
1
- /** Smallest positive number distinguishable from zero in floating-point comparisons. */
1
+ /**
2
+ * Control-point distance, as a fraction of the radius, for approximating a quarter circle with one
3
+ * cubic Bezier: `4 * (sqrt(2) - 1) / 3`.
4
+ *
5
+ * Named for the circle that defines it rather than the arcs that use it. Written as a literal and
6
+ * pinned to that formula by the colocated test, which IS the recomputation a transcribed decimal
7
+ * would otherwise lack — the digits are long enough that a wrong one reads as correct and still
8
+ * draws a circle that looks round.
9
+ *
10
+ * A literal rather than the expression because `Math.SQRT2` is a property of a mutable global: no
11
+ * correct minifier may evaluate `4 * (Math.SQRT2 - 1) / 3` at build time, so that form reaches the
12
+ * bundle as a runtime computation of a compile-time-known number. Neither form is inlined at its
13
+ * use sites and both measure the same gzipped size, so this buys evaluation, not bytes.
14
+ */
15
+ export declare const CIRCLE_KAPPA = 0.5522847498307936;
16
+ /** Default absolute tolerance for approximate floating-point comparisons. */
2
17
  export declare const EPSILON = 0.000001;
3
18
  /** Full circle in radians (2π). Prefer `TAU` over `2 * Math.PI` for clarity. */
4
19
  export declare const TAU: number;
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,eAAO,MAAM,OAAO,WAAO,CAAC;AAE5B,gFAAgF;AAChF,eAAO,MAAM,GAAG,QAAc,CAAC;AAE/B,yBAAyB;AACzB,eAAO,MAAM,OAAO,QAAc,CAAC;AAEnC,wDAAwD;AACxD,eAAO,MAAM,UAAU,QAAgB,CAAC;AAExC,wDAAwD;AACxD,eAAO,MAAM,UAAU,QAAgB,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,YAAY,qBAAqB,CAAC;AAE/C,6EAA6E;AAC7E,eAAO,MAAM,OAAO,WAAO,CAAC;AAE5B,gFAAgF;AAChF,eAAO,MAAM,GAAG,QAAc,CAAC;AAE/B,yBAAyB;AACzB,eAAO,MAAM,OAAO,QAAc,CAAC;AAEnC,wDAAwD;AACxD,eAAO,MAAM,UAAU,QAAgB,CAAC;AAExC,wDAAwD;AACxD,eAAO,MAAM,UAAU,QAAgB,CAAC"}
package/dist/constants.js CHANGED
@@ -1,4 +1,19 @@
1
- /** Smallest positive number distinguishable from zero in floating-point comparisons. */
1
+ /**
2
+ * Control-point distance, as a fraction of the radius, for approximating a quarter circle with one
3
+ * cubic Bezier: `4 * (sqrt(2) - 1) / 3`.
4
+ *
5
+ * Named for the circle that defines it rather than the arcs that use it. Written as a literal and
6
+ * pinned to that formula by the colocated test, which IS the recomputation a transcribed decimal
7
+ * would otherwise lack — the digits are long enough that a wrong one reads as correct and still
8
+ * draws a circle that looks round.
9
+ *
10
+ * A literal rather than the expression because `Math.SQRT2` is a property of a mutable global: no
11
+ * correct minifier may evaluate `4 * (Math.SQRT2 - 1) / 3` at build time, so that form reaches the
12
+ * bundle as a runtime computation of a compile-time-known number. Neither form is inlined at its
13
+ * use sites and both measure the same gzipped size, so this buys evaluation, not bytes.
14
+ */
15
+ export const CIRCLE_KAPPA = 0.5522847498307936;
16
+ /** Default absolute tolerance for approximate floating-point comparisons. */
2
17
  export const EPSILON = 1e-6;
3
18
  /** Full circle in radians (2π). Prefer `TAU` over `2 * Math.PI` for clarity. */
4
19
  export const TAU = Math.PI * 2;
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC;AAE5B,gFAAgF;AAChF,MAAM,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;AAE/B,yBAAyB;AACzB,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;AAEnC,wDAAwD;AACxD,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC;AAExC,wDAAwD;AACxD,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,kBAAkB,CAAC;AAE/C,6EAA6E;AAC7E,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC;AAE5B,gFAAgF;AAChF,MAAM,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;AAE/B,yBAAyB;AACzB,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;AAEnC,wDAAwD;AACxD,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC;AAExC,wDAAwD;AACxD,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
- export { DEG_TO_RAD, EPSILON, HALF_PI, RAD_TO_DEG, RandomSource, TAU, approxEqual, approxEqualRelative, approxZero, ceilPowerOfTwo, ceilTo, clamp, createRandomSource, createRandomSourceFromHash, damp, degToRad, deltaAngle, euclideanMod, factorial, floorPowerOfTwo, floorTo, fract, gcd, hash2D, hash3D, hashCombine, hashUint32, hypot2, inRange, inverseLerp, isEven, isOdd, isPowerOfTwo, lcm, lerp, lerpAngle, mean, median, moveTowards, nextMultipleOf, nextPowerOfTwo, normalizeAngle, pick, pingPong, previousPowerOfTwo, quantize, radToDeg, randomBool, randomExponential, randomGaussian, randomGaussianPair, randomInsideUnitDisc, randomInsideUnitSphere, randomInt, randomOnUnitCircle, randomOnUnitSphere, randomPoisson, randomRange, randomSign, randomWeighted, remap, repeat, roundTo, saturate, shuffle, shuffleInPlace, sign, smoothStep, smootherStep, standardDeviation, step, variance, weightedAverage, } from './contract';
1
+ export { CIRCLE_KAPPA, DEG_TO_RAD, EPSILON, HALF_PI, RAD_TO_DEG, TAU, approxEqual, approxEqualRelative, approxZero, ceilPowerOfTwo, ceilTo, clamp, createRandomSource, createRandomSourceFromHash, damp, degToRad, deltaAngle, euclideanMod, factorial, floorPowerOfTwo, floorTo, fract, gcd, hash2D, hash3D, hashCombine, hashUint32, hypot2, inRange, inverseLerp, isEven, isOdd, isPowerOfTwo, lcm, lerp, lerpAngle, mean, median, moveTowards, nextMultipleOf, nextPowerOfTwo, normalizeAngle, pick, pingPong, previousPowerOfTwo, quantize, radToDeg, randomBool, randomExponential, randomGaussian, randomGaussianPair, randomInsideUnitDisc, randomInsideUnitSphere, randomInt, randomOnUnitCircle, randomOnUnitSphere, randomPoisson, randomRange, randomSign, randomWeighted, remap, repeat, roundTo, saturate, shuffle, shuffleInPlace, sign, smoothStep, smootherStep, standardDeviation, step, variance, weightedAverage, } from './contract';
2
+ export type { RandomSource } from './contract';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,OAAO,EACP,OAAO,EACP,UAAU,EACV,YAAY,EACZ,GAAG,EACH,WAAW,EACX,mBAAmB,EACnB,UAAU,EACV,cAAc,EACd,MAAM,EACN,KAAK,EACL,kBAAkB,EAClB,0BAA0B,EAC1B,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,SAAS,EACT,eAAe,EACf,OAAO,EACP,KAAK,EACL,GAAG,EACH,MAAM,EACN,MAAM,EACN,WAAW,EACX,UAAU,EACV,MAAM,EACN,OAAO,EACP,WAAW,EACX,MAAM,EACN,KAAK,EACL,YAAY,EACZ,GAAG,EACH,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,MAAM,EACN,WAAW,EACX,cAAc,EACd,cAAc,EACd,cAAc,EACd,IAAI,EACJ,QAAQ,EACR,kBAAkB,EAClB,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,EACtB,SAAS,EACT,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,UAAU,EACV,cAAc,EACd,KAAK,EACL,MAAM,EACN,OAAO,EACP,QAAQ,EACR,OAAO,EACP,cAAc,EACd,IAAI,EACJ,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,IAAI,EACJ,QAAQ,EACR,eAAe,GAChB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,UAAU,EACV,OAAO,EACP,OAAO,EACP,UAAU,EACV,GAAG,EACH,WAAW,EACX,mBAAmB,EACnB,UAAU,EACV,cAAc,EACd,MAAM,EACN,KAAK,EACL,kBAAkB,EAClB,0BAA0B,EAC1B,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,SAAS,EACT,eAAe,EACf,OAAO,EACP,KAAK,EACL,GAAG,EACH,MAAM,EACN,MAAM,EACN,WAAW,EACX,UAAU,EACV,MAAM,EACN,OAAO,EACP,WAAW,EACX,MAAM,EACN,KAAK,EACL,YAAY,EACZ,GAAG,EACH,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,MAAM,EACN,WAAW,EACX,cAAc,EACd,cAAc,EACd,cAAc,EACd,IAAI,EACJ,QAAQ,EACR,kBAAkB,EAClB,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,EACtB,SAAS,EACT,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,UAAU,EACV,cAAc,EACd,KAAK,EACL,MAAM,EACN,OAAO,EACP,QAAQ,EACR,OAAO,EACP,cAAc,EACd,IAAI,EACJ,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,IAAI,EACJ,QAAQ,EACR,eAAe,GAChB,MAAM,YAAY,CAAC;AAKpB,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { DEG_TO_RAD, EPSILON, HALF_PI, RAD_TO_DEG, TAU, approxEqual, approxEqualRelative, approxZero, ceilPowerOfTwo, ceilTo, clamp, createRandomSource, createRandomSourceFromHash, damp, degToRad, deltaAngle, euclideanMod, factorial, floorPowerOfTwo, floorTo, fract, gcd, hash2D, hash3D, hashCombine, hashUint32, hypot2, inRange, inverseLerp, isEven, isOdd, isPowerOfTwo, lcm, lerp, lerpAngle, mean, median, moveTowards, nextMultipleOf, nextPowerOfTwo, normalizeAngle, pick, pingPong, previousPowerOfTwo, quantize, radToDeg, randomBool, randomExponential, randomGaussian, randomGaussianPair, randomInsideUnitDisc, randomInsideUnitSphere, randomInt, randomOnUnitCircle, randomOnUnitSphere, randomPoisson, randomRange, randomSign, randomWeighted, remap, repeat, roundTo, saturate, shuffle, shuffleInPlace, sign, smoothStep, smootherStep, standardDeviation, step, variance, weightedAverage, } from './contract';
1
+ export { CIRCLE_KAPPA, DEG_TO_RAD, EPSILON, HALF_PI, RAD_TO_DEG, TAU, approxEqual, approxEqualRelative, approxZero, ceilPowerOfTwo, ceilTo, clamp, createRandomSource, createRandomSourceFromHash, damp, degToRad, deltaAngle, euclideanMod, factorial, floorPowerOfTwo, floorTo, fract, gcd, hash2D, hash3D, hashCombine, hashUint32, hypot2, inRange, inverseLerp, isEven, isOdd, isPowerOfTwo, lcm, lerp, lerpAngle, mean, median, moveTowards, nextMultipleOf, nextPowerOfTwo, normalizeAngle, pick, pingPong, previousPowerOfTwo, quantize, radToDeg, randomBool, randomExponential, randomGaussian, randomGaussianPair, randomInsideUnitDisc, randomInsideUnitSphere, randomInt, randomOnUnitCircle, randomOnUnitSphere, randomPoisson, randomRange, randomSign, randomWeighted, remap, repeat, roundTo, saturate, shuffle, shuffleInPlace, sign, smoothStep, smootherStep, standardDeviation, step, variance, weightedAverage, } from './contract';
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,OAAO,EACP,OAAO,EACP,UAAU,EAEV,GAAG,EACH,WAAW,EACX,mBAAmB,EACnB,UAAU,EACV,cAAc,EACd,MAAM,EACN,KAAK,EACL,kBAAkB,EAClB,0BAA0B,EAC1B,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,SAAS,EACT,eAAe,EACf,OAAO,EACP,KAAK,EACL,GAAG,EACH,MAAM,EACN,MAAM,EACN,WAAW,EACX,UAAU,EACV,MAAM,EACN,OAAO,EACP,WAAW,EACX,MAAM,EACN,KAAK,EACL,YAAY,EACZ,GAAG,EACH,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,MAAM,EACN,WAAW,EACX,cAAc,EACd,cAAc,EACd,cAAc,EACd,IAAI,EACJ,QAAQ,EACR,kBAAkB,EAClB,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,EACtB,SAAS,EACT,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,UAAU,EACV,cAAc,EACd,KAAK,EACL,MAAM,EACN,OAAO,EACP,QAAQ,EACR,OAAO,EACP,cAAc,EACd,IAAI,EACJ,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,IAAI,EACJ,QAAQ,EACR,eAAe,GAChB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,UAAU,EACV,OAAO,EACP,OAAO,EACP,UAAU,EACV,GAAG,EACH,WAAW,EACX,mBAAmB,EACnB,UAAU,EACV,cAAc,EACd,MAAM,EACN,KAAK,EACL,kBAAkB,EAClB,0BAA0B,EAC1B,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,SAAS,EACT,eAAe,EACf,OAAO,EACP,KAAK,EACL,GAAG,EACH,MAAM,EACN,MAAM,EACN,WAAW,EACX,UAAU,EACV,MAAM,EACN,OAAO,EACP,WAAW,EACX,MAAM,EACN,KAAK,EACL,YAAY,EACZ,GAAG,EACH,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,MAAM,EACN,WAAW,EACX,cAAc,EACd,cAAc,EACd,cAAc,EACd,IAAI,EACJ,QAAQ,EACR,kBAAkB,EAClB,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,EACtB,SAAS,EACT,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,UAAU,EACV,cAAc,EACd,KAAK,EACL,MAAM,EACN,OAAO,EACP,QAAQ,EACR,OAAO,EACP,cAAc,EACd,IAAI,EACJ,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,IAAI,EACJ,QAAQ,EACR,eAAe,GAChB,MAAM,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"interpolationAdvanced.d.ts","sourceRoot":"","sources":["../src/interpolationAdvanced.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAG/F;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAKjE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIrF;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAK1D;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAGxD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAI5E"}
1
+ {"version":3,"file":"interpolationAdvanced.d.ts","sourceRoot":"","sources":["../src/interpolationAdvanced.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAG/F;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAKjE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIrF;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAQ1D;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAMxD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAI5E"}
@@ -42,8 +42,10 @@ export function moveTowards(current, target, maxDelta) {
42
42
  * `pingPong(t, 1)` cycles: 0 → 1 → 0 → 1 → …
43
43
  */
44
44
  export function pingPong(t, length) {
45
- if (length <= 0)
46
- return 0;
45
+ // No guard on a non-positive length: the arithmetic yields NaN and NaN PROPAGATES. These functions do not
46
+ // invent values — a silent 0 turns a loud upstream failure into a plausible number, and IEEE propagation
47
+ // lowers for free where an explicit branch does not. Callers who want a warning get one from a guard
48
+ // layer, not from silent coercion here.
47
49
  const cycle = 2 * length;
48
50
  const mod = ((t % cycle) + cycle) % cycle;
49
51
  return mod <= length ? mod : cycle - mod;
@@ -53,8 +55,10 @@ export function pingPong(t, length) {
53
55
  * `repeat(1.6, 1)` → `0.6`. Analogous to Unity's `Mathf.Repeat`.
54
56
  */
55
57
  export function repeat(t, length) {
56
- if (length <= 0)
57
- return 0;
58
+ // No guard on a non-positive length: the arithmetic yields NaN and NaN PROPAGATES. These functions do not
59
+ // invent values — a silent 0 turns a loud upstream failure into a plausible number, and IEEE propagation
60
+ // lowers for free where an explicit branch does not. Callers who want a warning get one from a guard
61
+ // layer, not from silent coercion here.
58
62
  return ((t % length) + length) % length;
59
63
  }
60
64
  /** Hermite interpolation with a smoother quintic ease curve (Ken Perlin).
@@ -1 +1 @@
1
- {"version":3,"file":"interpolationAdvanced.js","sourceRoot":"","sources":["../src/interpolationAdvanced.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,UAAU,IAAI,CAAC,OAAe,EAAE,MAAc,EAAE,MAAc,EAAE,SAAiB;IACrF,IAAI,SAAS,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,OAAO,CAAC;IAClD,OAAO,MAAM,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;AACrE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS;IACvD,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;IACxB,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;IACzC,IAAI,IAAI,GAAG,IAAI,CAAC,EAAE;QAAE,IAAI,IAAI,GAAG,CAAC;IAChC,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;AACtB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,MAAc,EAAE,QAAgB;IAC3E,MAAM,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;IAC/B,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,QAAQ;QAAE,OAAO,MAAM,CAAC;IAC/C,OAAO,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;AAC/C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,CAAS,EAAE,MAAc;IAChD,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAC1B,MAAM,KAAK,GAAG,CAAC,GAAG,MAAM,CAAC;IACzB,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC;IAC1C,OAAO,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC;AAC3C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,MAAM,CAAC,CAAS,EAAE,MAAc;IAC9C,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAC1B,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC;AAC1C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,KAAa,EAAE,CAAS;IAClE,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;IACxC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;AAC7C,CAAC"}
1
+ {"version":3,"file":"interpolationAdvanced.js","sourceRoot":"","sources":["../src/interpolationAdvanced.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,UAAU,IAAI,CAAC,OAAe,EAAE,MAAc,EAAE,MAAc,EAAE,SAAiB;IACrF,IAAI,SAAS,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,OAAO,CAAC;IAClD,OAAO,MAAM,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;AACrE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS;IACvD,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;IACxB,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;IACzC,IAAI,IAAI,GAAG,IAAI,CAAC,EAAE;QAAE,IAAI,IAAI,GAAG,CAAC;IAChC,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;AACtB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,MAAc,EAAE,QAAgB;IAC3E,MAAM,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;IAC/B,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,QAAQ;QAAE,OAAO,MAAM,CAAC;IAC/C,OAAO,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;AAC/C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,CAAS,EAAE,MAAc;IAChD,0GAA0G;IAC1G,yGAAyG;IACzG,qGAAqG;IACrG,wCAAwC;IACxC,MAAM,KAAK,GAAG,CAAC,GAAG,MAAM,CAAC;IACzB,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC;IAC1C,OAAO,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC;AAC3C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,MAAM,CAAC,CAAS,EAAE,MAAc;IAC9C,0GAA0G;IAC1G,yGAAyG;IACzG,qGAAqG;IACrG,wCAAwC;IACxC,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC;AAC1C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,KAAa,EAAE,CAAS;IAClE,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;IACxC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;AAC7C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"nextPowerOfTwo.d.ts","sourceRoot":"","sources":["../src/nextPowerOfTwo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAItE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAWhD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAUpD"}
1
+ {"version":3,"file":"nextPowerOfTwo.d.ts","sourceRoot":"","sources":["../src/nextPowerOfTwo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAItE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAWhD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAepD"}
@@ -41,12 +41,17 @@ export function previousPowerOfTwo(n) {
41
41
  if (n <= 1)
42
42
  return 1;
43
43
  // Fill all bits below the highest set bit, then shift right by 1.
44
+ //
45
+ // The shift is UNSIGNED, matching nextPowerOfTwo's `>>> 0`. With a signed `>>` the fill leaves bit 31 set
46
+ // for any input at or above 2^30, and sign extension then returned a NEGATIVE power of two — -1073741824
47
+ // for both 2^30 and 2^31-1. The two functions are mirror images and the operator is the only place they
48
+ // were allowed to differ.
44
49
  n = n | 0;
45
50
  n |= n >> 1;
46
51
  n |= n >> 2;
47
52
  n |= n >> 4;
48
53
  n |= n >> 8;
49
54
  n |= n >> 16;
50
- return (n + 1) >> 1;
55
+ return (n + 1) >>> 1;
51
56
  }
52
57
  //# sourceMappingURL=nextPowerOfTwo.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"nextPowerOfTwo.js","sourceRoot":"","sources":["../src/nextPowerOfTwo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,CAAS;IACpC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AACtC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,KAAa,EAAE,QAAgB;IAC5D,IAAI,QAAQ,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAChC,MAAM,SAAS,GAAG,KAAK,GAAG,QAAQ,CAAC;IACnC,OAAO,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,CAAS;IACtC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACrB,qEAAqE;IACrE,4DAA4D;IAC5D,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAChB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACZ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACb,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,CAAS;IAC1C,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACrB,kEAAkE;IAClE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACV,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACZ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACb,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AACtB,CAAC"}
1
+ {"version":3,"file":"nextPowerOfTwo.js","sourceRoot":"","sources":["../src/nextPowerOfTwo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,CAAS;IACpC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AACtC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,KAAa,EAAE,QAAgB;IAC5D,IAAI,QAAQ,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAChC,MAAM,SAAS,GAAG,KAAK,GAAG,QAAQ,CAAC;IACnC,OAAO,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,CAAS;IACtC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACrB,qEAAqE;IACrE,4DAA4D;IAC5D,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAChB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACZ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACb,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,CAAS;IAC1C,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACrB,kEAAkE;IAClE,EAAE;IACF,0GAA0G;IAC1G,yGAAyG;IACzG,wGAAwG;IACxG,0BAA0B;IAC1B,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACV,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACZ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACb,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC"}
@@ -8,8 +8,8 @@ export declare function factorial(n: number): number;
8
8
  /** Return the greatest common divisor of `a` and `b` (Euclidean algorithm).
9
9
  *
10
10
  * Operates on the absolute values of the inputs, so negative arguments are
11
- * accepted. Throws when both `a` and `b` are `0` (programmer error — the GCD
12
- * of zero and zero is undefined).
11
+ * accepted. Throws for non-finite inputs or when both `a` and `b` are `0`
12
+ * (programmer errors — the GCD of zero and zero is undefined).
13
13
  */
14
14
  export declare function gcd(a: number, b: number): number;
15
15
  /** Return the squared distance `x² + y²`.
@@ -1 +1 @@
1
- {"version":3,"file":"numberTheory.d.ts","sourceRoot":"","sources":["../src/numberTheory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAM3C;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAUhD;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,oCAAoC;AACpC,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAEzC;AAED,mCAAmC;AACnC,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAExC;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAGhD"}
1
+ {"version":3,"file":"numberTheory.d.ts","sourceRoot":"","sources":["../src/numberTheory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAM3C;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAahD;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,oCAAoC;AACpC,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAEzC;AAED,mCAAmC;AACnC,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAExC;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAGhD"}
@@ -17,10 +17,13 @@ export function factorial(n) {
17
17
  /** Return the greatest common divisor of `a` and `b` (Euclidean algorithm).
18
18
  *
19
19
  * Operates on the absolute values of the inputs, so negative arguments are
20
- * accepted. Throws when both `a` and `b` are `0` (programmer error — the GCD
21
- * of zero and zero is undefined).
20
+ * accepted. Throws for non-finite inputs or when both `a` and `b` are `0`
21
+ * (programmer errors — the GCD of zero and zero is undefined).
22
22
  */
23
23
  export function gcd(a, b) {
24
+ if (!Number.isFinite(a) || !Number.isFinite(b)) {
25
+ throw new RangeError('gcd: arguments must be finite');
26
+ }
24
27
  a = Math.abs(Math.trunc(a));
25
28
  b = Math.abs(Math.trunc(b));
26
29
  if (a === 0 && b === 0)
@@ -1 +1 @@
1
- {"version":3,"file":"numberTheory.js","sourceRoot":"","sources":["../src/numberTheory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,CAAS;IACjC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,6CAA6C,CAAC,CAAC;IACvG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACjC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;QAAE,MAAM,IAAI,CAAC,CAAC;IACzC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CAAC,CAAS,EAAE,CAAS;IACtC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,mCAAmC,CAAC,CAAC;IAClF,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACf,MAAM,CAAC,GAAG,CAAC,CAAC;QACZ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACV,CAAC,GAAG,CAAC,CAAC;IACR,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAC,CAAS,EAAE,CAAS;IACzC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACvB,CAAC;AAED,oCAAoC;AACpC,MAAM,UAAU,MAAM,CAAC,CAAS;IAC9B,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,KAAK,CAAC,CAAS;IAC7B,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CAAC,CAAS,EAAE,CAAS;IACtC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACpB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC"}
1
+ {"version":3,"file":"numberTheory.js","sourceRoot":"","sources":["../src/numberTheory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,CAAS;IACjC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,6CAA6C,CAAC,CAAC;IACvG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACjC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;QAAE,MAAM,IAAI,CAAC,CAAC;IACzC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CAAC,CAAS,EAAE,CAAS;IACtC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,UAAU,CAAC,+BAA+B,CAAC,CAAC;IACxD,CAAC;IACD,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,mCAAmC,CAAC,CAAC;IAClF,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACf,MAAM,CAAC,GAAG,CAAC,CAAC;QACZ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACV,CAAC,GAAG,CAAC,CAAC;IACR,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAC,CAAS,EAAE,CAAS;IACzC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACvB,CAAC;AAED,oCAAoC;AACpC,MAAM,UAAU,MAAM,CAAC,CAAS;IAC9B,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,KAAK,CAAC,CAAS;IAC7B,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CAAC,CAAS,EAAE,CAAS;IACtC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACpB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC"}
@@ -11,7 +11,7 @@ export declare function pick<T>(random: RandomSource, items: Readonly<T[]>): T |
11
11
  * Suitable for modeling inter-arrival times in a Poisson process, particle
12
12
  * lifetimes, and decay events.
13
13
  *
14
- * The result is always non-negative. Throws if `rate <= 0`.
14
+ * The result is always non-negative. Throws if `rate` is non-finite or not positive.
15
15
  *
16
16
  * Deterministic: same `random` sequence → same output sequence.
17
17
  */
@@ -78,7 +78,7 @@ export declare function randomOnUnitSphere(random: RandomSource, out: Vector3Lik
78
78
  * `lambda` (λ ≤ ~30); for large lambda, `randomGaussian(random, lambda,
79
79
  * Math.sqrt(lambda))` is a faster approximation.
80
80
  *
81
- * The result is a non-negative integer. Throws if `lambda <= 0`.
81
+ * The result is a non-negative integer. Throws if `lambda` is non-finite or not positive.
82
82
  *
83
83
  * Deterministic: same `random` sequence → same output sequence.
84
84
  */
@@ -1 +1 @@
1
- {"version":3,"file":"randomDistributions.d.ts","sourceRoot":"","sources":["../src/randomDistributions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvF;;;GAGG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS,CAGjF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,GAAE,MAAU,GAAG,MAAM,CAKhF;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,GAAE,MAAU,EAAE,iBAAiB,GAAE,MAAU,GAAG,MAAM,CAO5G;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,YAAY,EACpB,IAAI,GAAE,MAAU,EAChB,iBAAiB,GAAE,MAAU,GAC5B,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAQ3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAUjF;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAYnF;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAM/E;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAiB/E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,GAAE,MAAU,GAAG,MAAM,CAU9E;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,CAUxF;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAI1E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,CAOxE"}
1
+ {"version":3,"file":"randomDistributions.d.ts","sourceRoot":"","sources":["../src/randomDistributions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvF;;;GAGG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS,CAGjF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,GAAE,MAAU,GAAG,MAAM,CAOhF;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,GAAE,MAAU,EAAE,iBAAiB,GAAE,MAAU,GAAG,MAAM,CAO5G;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,YAAY,EACpB,IAAI,GAAE,MAAU,EAChB,iBAAiB,GAAE,MAAU,GAC5B,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAQ3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAUjF;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAYnF;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAM/E;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAiB/E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,GAAE,MAAU,GAAG,MAAM,CAY9E;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,CAUxF;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAI1E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,CAOxE"}
@@ -14,13 +14,14 @@ export function pick(random, items) {
14
14
  * Suitable for modeling inter-arrival times in a Poisson process, particle
15
15
  * lifetimes, and decay events.
16
16
  *
17
- * The result is always non-negative. Throws if `rate <= 0`.
17
+ * The result is always non-negative. Throws if `rate` is non-finite or not positive.
18
18
  *
19
19
  * Deterministic: same `random` sequence → same output sequence.
20
20
  */
21
21
  export function randomExponential(random, rate = 1) {
22
- if (rate <= 0)
23
- throw new RangeError('randomExponential: rate must be > 0');
22
+ if (!Number.isFinite(rate) || rate <= 0) {
23
+ throw new RangeError('randomExponential: rate must be finite and > 0');
24
+ }
24
25
  const u = random();
25
26
  // Avoid ln(0) — replace exactly 0 with the smallest usable positive value.
26
27
  return -Math.log(u === 0 ? Number.EPSILON : u) / rate;
@@ -147,13 +148,14 @@ export function randomOnUnitSphere(random, out) {
147
148
  * `lambda` (λ ≤ ~30); for large lambda, `randomGaussian(random, lambda,
148
149
  * Math.sqrt(lambda))` is a faster approximation.
149
150
  *
150
- * The result is a non-negative integer. Throws if `lambda <= 0`.
151
+ * The result is a non-negative integer. Throws if `lambda` is non-finite or not positive.
151
152
  *
152
153
  * Deterministic: same `random` sequence → same output sequence.
153
154
  */
154
155
  export function randomPoisson(random, lambda = 1) {
155
- if (lambda <= 0)
156
- throw new RangeError('randomPoisson: lambda must be > 0');
156
+ if (!Number.isFinite(lambda) || lambda <= 0) {
157
+ throw new RangeError('randomPoisson: lambda must be finite and > 0');
158
+ }
157
159
  const limit = Math.exp(-lambda);
158
160
  let k = 0;
159
161
  let product = random();
@@ -1 +1 @@
1
- {"version":3,"file":"randomDistributions.js","sourceRoot":"","sources":["../src/randomDistributions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"randomDistributions.js","sourceRoot":"","sources":["../src/randomDistributions.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,13 @@
1
1
  import type { RandomSource } from '@flighthq/types/contract';
2
2
  /** Return a random boolean with the given `probability` of being `true`.
3
3
  *
4
- * `probability` is clamped to `[0, 1]`; `0.5` is a fair coin flip.
4
+ * Values outside `[0, 1]` behave like the nearest endpoint; `0.5` is a fair coin flip.
5
5
  */
6
6
  export declare function randomBool(random: RandomSource, probability?: number): boolean;
7
7
  /** Return a random integer in the inclusive range `[min, max]`.
8
8
  *
9
- * Both bounds must be integers; the function passes them through `Math.floor`
10
- * so non-integer bounds are truncated toward zero rather than throwing. Throws
11
- * if `min > max`.
9
+ * Bounds are passed through `Math.floor`, so fractional bounds are rounded down
10
+ * rather than rejected. Throws if the resulting `min` is greater than `max`.
12
11
  */
13
12
  export declare function randomInt(random: RandomSource, min: number, max: number): number;
14
13
  /** Return a random float in the half-open range `[min, max)`. */
@@ -1 +1 @@
1
- {"version":3,"file":"randomRange.d.ts","sourceRoot":"","sources":["../src/randomRange.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,GAAE,MAAY,GAAG,OAAO,CAEnF;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAKhF;AAED,iEAAiE;AACjE,wBAAgB,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAElF;AAED,uEAAuE;AACvE,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAEvD"}
1
+ {"version":3,"file":"randomRange.d.ts","sourceRoot":"","sources":["../src/randomRange.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,GAAE,MAAY,GAAG,OAAO,CAEnF;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAKhF;AAED,iEAAiE;AACjE,wBAAgB,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAElF;AAED,uEAAuE;AACvE,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAEvD"}
@@ -1,15 +1,14 @@
1
1
  /** Return a random boolean with the given `probability` of being `true`.
2
2
  *
3
- * `probability` is clamped to `[0, 1]`; `0.5` is a fair coin flip.
3
+ * Values outside `[0, 1]` behave like the nearest endpoint; `0.5` is a fair coin flip.
4
4
  */
5
5
  export function randomBool(random, probability = 0.5) {
6
6
  return random() < probability;
7
7
  }
8
8
  /** Return a random integer in the inclusive range `[min, max]`.
9
9
  *
10
- * Both bounds must be integers; the function passes them through `Math.floor`
11
- * so non-integer bounds are truncated toward zero rather than throwing. Throws
12
- * if `min > max`.
10
+ * Bounds are passed through `Math.floor`, so fractional bounds are rounded down
11
+ * rather than rejected. Throws if the resulting `min` is greater than `max`.
13
12
  */
14
13
  export function randomInt(random, min, max) {
15
14
  const lo = Math.floor(min);
@@ -1 +1 @@
1
- {"version":3,"file":"randomRange.js","sourceRoot":"","sources":["../src/randomRange.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,MAAoB,EAAE,cAAsB,GAAG;IACxE,OAAO,MAAM,EAAE,GAAG,WAAW,CAAC;AAChC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,MAAoB,EAAE,GAAW,EAAE,GAAW;IACtE,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,EAAE,GAAG,EAAE;QAAE,MAAM,IAAI,UAAU,CAAC,+BAA+B,CAAC,CAAC;IACnE,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,WAAW,CAAC,MAAoB,EAAE,GAAW,EAAE,GAAW;IACxE,OAAO,GAAG,GAAG,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;AACtC,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,UAAU,CAAC,MAAoB;IAC7C,OAAO,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"randomRange.js","sourceRoot":"","sources":["../src/randomRange.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,MAAoB,EAAE,cAAsB,GAAG;IACxE,OAAO,MAAM,EAAE,GAAG,WAAW,CAAC;AAChC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,MAAoB,EAAE,GAAW,EAAE,GAAW;IACtE,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,EAAE,GAAG,EAAE;QAAE,MAAM,IAAI,UAAU,CAAC,+BAA+B,CAAC,CAAC;IACnE,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,WAAW,CAAC,MAAoB,EAAE,GAAW,EAAE,GAAW;IACxE,OAAO,GAAG,GAAG,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;AACtC,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,UAAU,CAAC,MAAoB;IAC7C,OAAO,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"statistics.d.ts","sourceRoot":"","sources":["../src/statistics.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,CAKvD;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,CAKzD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,CAEpE;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,CAS3D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,CAY/F"}
1
+ {"version":3,"file":"statistics.d.ts","sourceRoot":"","sources":["../src/statistics.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,CAMvD;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,CAKzD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,CAMpE;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,CAQ3D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,CAwB/F"}
@@ -5,10 +5,12 @@
5
5
  export function mean(values) {
6
6
  if (values.length === 0)
7
7
  return NaN;
8
- let sum = 0;
9
- for (let i = 0; i < values.length; i++)
10
- sum += values[i];
11
- return sum / values.length;
8
+ const scale = finiteAbsoluteScale(values);
9
+ if (!Number.isFinite(scale))
10
+ return unscaledMean(values);
11
+ if (scale === 0)
12
+ return 0;
13
+ return (scaledSum(values, scale) / values.length) * scale;
12
14
  }
13
15
  /** Return the median of `values`.
14
16
  *
@@ -20,14 +22,21 @@ export function median(values) {
20
22
  return NaN;
21
23
  const sorted = values.slice().sort((a, b) => a - b);
22
24
  const mid = Math.floor(sorted.length / 2);
23
- return sorted.length % 2 !== 0 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
25
+ return sorted.length % 2 !== 0 ? sorted[mid] : midpoint(sorted[mid - 1], sorted[mid]);
24
26
  }
25
27
  /** Return the population standard deviation of `values`.
26
28
  *
27
29
  * Returns `NaN` for an empty array.
28
30
  */
29
31
  export function standardDeviation(values) {
30
- return Math.sqrt(variance(values));
32
+ if (values.length === 0)
33
+ return NaN;
34
+ const scale = finiteAbsoluteScale(values);
35
+ if (!Number.isFinite(scale))
36
+ return Math.sqrt(unscaledVariance(values));
37
+ if (scale === 0)
38
+ return 0;
39
+ return Math.sqrt(scaledVariance(values, scale)) * scale;
31
40
  }
32
41
  /** Return the population variance of `values`.
33
42
  *
@@ -36,13 +45,15 @@ export function standardDeviation(values) {
36
45
  export function variance(values) {
37
46
  if (values.length === 0)
38
47
  return NaN;
39
- const m = mean(values);
40
- let sum = 0;
41
- for (let i = 0; i < values.length; i++) {
42
- const d = values[i] - m;
43
- sum += d * d;
44
- }
45
- return sum / values.length;
48
+ const scale = finiteAbsoluteScale(values);
49
+ if (!Number.isFinite(scale))
50
+ return unscaledVariance(values);
51
+ if (scale === 0)
52
+ return 0;
53
+ const normalized = scaledVariance(values, scale);
54
+ if (normalized === 0)
55
+ return 0;
56
+ return normalized * scale * scale;
46
57
  }
47
58
  /** Return the weighted average of `values` using `weights`.
48
59
  *
@@ -56,6 +67,83 @@ export function weightedAverage(values, weights) {
56
67
  }
57
68
  if (values.length === 0)
58
69
  return NaN;
70
+ const valueScale = finiteAbsoluteScale(values);
71
+ const weightScale = finiteAbsoluteScale(weights);
72
+ if (!Number.isFinite(valueScale) || !Number.isFinite(weightScale)) {
73
+ return unscaledWeightedAverage(values, weights);
74
+ }
75
+ if (weightScale === 0)
76
+ return NaN;
77
+ const sumWeights = scaledSum(weights, weightScale);
78
+ if (sumWeights === 0)
79
+ return NaN;
80
+ if (valueScale === 0)
81
+ return 0;
82
+ let sumProduct = 0;
83
+ let correction = 0;
84
+ for (let i = 0; i < values.length; i++) {
85
+ const term = (values[i] / valueScale) * (weights[i] / weightScale) - correction;
86
+ const next = sumProduct + term;
87
+ correction = next - sumProduct - term;
88
+ sumProduct = next;
89
+ }
90
+ return (sumProduct / sumWeights) * valueScale;
91
+ }
92
+ function finiteAbsoluteScale(values) {
93
+ let scale = 0;
94
+ for (let i = 0; i < values.length; i++)
95
+ scale = Math.max(scale, Math.abs(values[i]));
96
+ return scale;
97
+ }
98
+ function midpoint(a, b) {
99
+ if (!Number.isFinite(a) || !Number.isFinite(b))
100
+ return (a + b) / 2;
101
+ if (Object.is(a, b))
102
+ return a;
103
+ if ((a >= 0 && b >= 0) || (a <= 0 && b <= 0))
104
+ return a + (b - a) / 2;
105
+ return a / 2 + b / 2;
106
+ }
107
+ function scaledSum(values, scale) {
108
+ let sum = 0;
109
+ let correction = 0;
110
+ for (let i = 0; i < values.length; i++) {
111
+ const term = values[i] / scale - correction;
112
+ const next = sum + term;
113
+ correction = next - sum - term;
114
+ sum = next;
115
+ }
116
+ return sum;
117
+ }
118
+ function scaledVariance(values, scale) {
119
+ const normalizedMean = scaledSum(values, scale) / values.length;
120
+ let sum = 0;
121
+ let correction = 0;
122
+ for (let i = 0; i < values.length; i++) {
123
+ const difference = values[i] / scale - normalizedMean;
124
+ const term = difference * difference - correction;
125
+ const next = sum + term;
126
+ correction = next - sum - term;
127
+ sum = next;
128
+ }
129
+ return Math.max(0, sum / values.length);
130
+ }
131
+ function unscaledMean(values) {
132
+ let sum = 0;
133
+ for (let i = 0; i < values.length; i++)
134
+ sum += values[i];
135
+ return sum / values.length;
136
+ }
137
+ function unscaledVariance(values) {
138
+ const average = unscaledMean(values);
139
+ let sum = 0;
140
+ for (let i = 0; i < values.length; i++) {
141
+ const difference = values[i] - average;
142
+ sum += difference * difference;
143
+ }
144
+ return sum / values.length;
145
+ }
146
+ function unscaledWeightedAverage(values, weights) {
59
147
  let sumWeights = 0;
60
148
  let sumProduct = 0;
61
149
  for (let i = 0; i < values.length; i++) {
@@ -1 +1 @@
1
- {"version":3,"file":"statistics.js","sourceRoot":"","sources":["../src/statistics.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,IAAI,CAAC,MAA0B;IAC7C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IACpC,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;IACzD,OAAO,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC;AAC7B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAC,MAA0B;IAC/C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IACpC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AACrF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAA0B;IAC1D,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,MAA0B;IACjD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IACpC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IACvB,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACxB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;IACD,OAAO,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC;AAC7B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,MAA0B,EAAE,OAA2B;IACrF,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC;QACrC,MAAM,IAAI,UAAU,CAAC,+DAA+D,CAAC,CAAC;IACxF,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IACpC,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,UAAU,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;QACzB,UAAU,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,GAAG,UAAU,CAAC;AAC1D,CAAC"}
1
+ {"version":3,"file":"statistics.js","sourceRoot":"","sources":["../src/statistics.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flighthq/math",
3
- "version": "0.3.0",
3
+ "version": "0.3.1-next.1041.35b950c",
4
4
  "author": "Joshua Granick and other contributors",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -38,7 +38,7 @@
38
38
  "clean:dist": "tsx ../../scripts/clean-package-dist.ts"
39
39
  },
40
40
  "dependencies": {
41
- "@flighthq/types": "0.3.0"
41
+ "@flighthq/types": "0.3.1-next.1041.35b950c"
42
42
  },
43
43
  "devDependencies": {
44
44
  "typescript": "^5.3.0"
package/src/angle.test.ts CHANGED
@@ -32,6 +32,9 @@ describe('deltaAngle', () => {
32
32
  it('returns a negative delta when the target is behind', () => {
33
33
  expect(deltaAngle(Math.PI / 2, 0)).toBeCloseTo(-Math.PI / 2, 10);
34
34
  });
35
+ it('keeps the positive half-turn in its documented (-π, π] range', () => {
36
+ expect(deltaAngle(0, Math.PI)).toBe(Math.PI);
37
+ });
35
38
  it('result is always within (-π, π]', () => {
36
39
  for (let i = -10; i <= 10; i++) {
37
40
  const d = deltaAngle(i, i + 3);
@@ -1,6 +1,37 @@
1
- import { DEG_TO_RAD, EPSILON, HALF_PI, RAD_TO_DEG, TAU } from './constants';
1
+ import { CIRCLE_KAPPA, DEG_TO_RAD, EPSILON, HALF_PI, RAD_TO_DEG, TAU } from './constants';
2
2
 
3
3
  describe('constants', () => {
4
+ describe('CIRCLE_KAPPA', () => {
5
+ // Asserted against the COMPUTED expression, never a transcribed decimal. A test that restates the
6
+ // digits agrees with a typo in them, which is how a wrong digit at the 13th decimal survived a
7
+ // full suite. Exact equality, not toBeCloseTo: the error this guards against is far smaller than
8
+ // any tolerance worth writing.
9
+ //
10
+ // MEASURED, not assumed: mutating the constant's 13th decimal from ...36 to ...46 and running
11
+ // the whole repository fails exactly ONE test of 17,045 — this one. The sweep below passes over
12
+ // the wrong digit, as does every path, shape and clip test. That is the entire case for pinning
13
+ // a literal to its formula here rather than trusting geometry to notice, and it is why the
14
+ // original wrong digit survived a full suite.
15
+ it('equals four thirds of the square root of two less one', () => {
16
+ expect(CIRCLE_KAPPA).toBe((4 * (Math.sqrt(2) - 1)) / 3);
17
+ });
18
+
19
+ it('sweeps a unit quarter circle when used as the cubic control distance', () => {
20
+ // Catches a wrong FORMULA, not a wrong digit — and only that. A mistyped decimal moves the
21
+ // swept radius far less than the cubic's own approximation error, so this cannot stand in for
22
+ // the exact equality above. What it does add is independence from it: if the constant and that
23
+ // assertion were ever edited to agree on a wrong expression, the geometry would still object.
24
+ const radiusAt = (t: number): number => {
25
+ const u = 1 - t;
26
+ const x = u * u * u + 3 * u * u * t + 3 * u * t * t * CIRCLE_KAPPA;
27
+ const y = 3 * u * u * t * CIRCLE_KAPPA + 3 * u * t * t + t * t * t;
28
+ return Math.hypot(x, y);
29
+ };
30
+
31
+ for (const t of [0, 0.25, 0.5, 0.75, 1]) expect(radiusAt(t)).toBeCloseTo(1, 3);
32
+ });
33
+ });
34
+
4
35
  describe('DEG_TO_RAD', () => {
5
36
  it('converts 180 degrees to π', () => {
6
37
  expect(180 * DEG_TO_RAD).toBeCloseTo(Math.PI, 10);
package/src/hash.test.ts CHANGED
@@ -63,6 +63,9 @@ describe('hashCombine', () => {
63
63
  it('produces different results for different seeds', () => {
64
64
  expect(hashCombine(1, 100)).not.toBe(hashCombine(2, 100));
65
65
  });
66
+ it('pins the complete multi-term mix with a known-answer vector', () => {
67
+ expect(hashCombine(100, 200)).toBe(3347962280);
68
+ });
66
69
  });
67
70
 
68
71
  describe('hashUint32', () => {
@@ -38,6 +38,10 @@ describe('lerpAngle', () => {
38
38
  const normalised = ((result % TAU) + TAU) % TAU;
39
39
  expect(normalised).toBeCloseTo(0, 5);
40
40
  });
41
+ it('takes the shortest arc clockwise across 0/2π', () => {
42
+ const result = lerpAngle(Math.PI * 0.1, Math.PI * 1.9, 0.5);
43
+ expect(result).toBeCloseTo(0, 10);
44
+ });
41
45
  it('returns a at t = 0', () => {
42
46
  expect(lerpAngle(1, 2, 0)).toBeCloseTo(1, 10);
43
47
  });
@@ -71,8 +75,11 @@ describe('pingPong', () => {
71
75
  it('bounces back at t = 1.5 * length', () => {
72
76
  expect(pingPong(1.5, 1)).toBeCloseTo(0.5, 10);
73
77
  });
74
- it('returns 0 when length is 0', () => {
75
- expect(pingPong(1, 0)).toBe(0);
78
+ // NaN, not 0. These functions do not invent values: a non-positive length has no wrap interval, the
79
+ // arithmetic yields NaN, and NaN propagates so an upstream failure stays visible. A silent 0 is a
80
+ // plausible number that hides the break — this assertion previously pinned that coercion.
81
+ it('propagates NaN when length is 0', () => {
82
+ expect(pingPong(1, 0)).toBeNaN();
76
83
  });
77
84
  it('works with larger lengths', () => {
78
85
  expect(pingPong(3, 2)).toBeCloseTo(1, 10);
@@ -91,8 +98,11 @@ describe('repeat', () => {
91
98
  expect(r).toBeGreaterThanOrEqual(0);
92
99
  expect(r).toBeLessThan(1);
93
100
  });
94
- it('returns 0 when length is 0', () => {
95
- expect(repeat(1, 0)).toBe(0);
101
+ // NaN, not 0. These functions do not invent values: a non-positive length has no wrap interval, the
102
+ // arithmetic yields NaN, and NaN propagates so an upstream failure stays visible. A silent 0 is a
103
+ // plausible number that hides the break — this assertion previously pinned that coercion.
104
+ it('propagates NaN when length is 0', () => {
105
+ expect(repeat(1, 0)).toBeNaN();
96
106
  });
97
107
  });
98
108
 
@@ -82,3 +82,14 @@ describe('previousPowerOfTwo', () => {
82
82
  expect(previousPowerOfTwo(1025)).toBe(1024);
83
83
  });
84
84
  });
85
+
86
+ describe('previousPowerOfTwo', () => {
87
+ // BY VALUE, not by sign: a `>= 0` assertion would pass against a still-broken version returning 0,
88
+ // which is exactly what input 2147483648 did before the fix. The signed `>>` returned -1073741824 for
89
+ // both of these inputs — the negative value is the thing being pinned.
90
+ it('returns a positive power of two at and above 2^30, where a signed shift sign-extended', () => {
91
+ expect(previousPowerOfTwo(1073741824)).toBe(1073741824);
92
+ expect(previousPowerOfTwo(2147483647)).toBe(1073741824);
93
+ expect(nextPowerOfTwo(1073741824)).toBe(1073741824);
94
+ });
95
+ });
@@ -40,6 +40,11 @@ describe('gcd', () => {
40
40
  it('throws when both arguments are 0', () => {
41
41
  expect(() => gcd(0, 0)).toThrow(RangeError);
42
42
  });
43
+ it('rejects non-finite inputs instead of returning a non-finite value or looping', () => {
44
+ expect(() => gcd(Infinity, 0)).toThrow(RangeError);
45
+ expect(() => gcd(0, -Infinity)).toThrow(RangeError);
46
+ expect(() => gcd(NaN, 0)).toThrow(RangeError);
47
+ });
43
48
  });
44
49
 
45
50
  describe('hypot2', () => {
@@ -92,4 +97,8 @@ describe('lcm', () => {
92
97
  it('accepts negative inputs', () => {
93
98
  expect(lcm(-4, 6)).toBe(12);
94
99
  });
100
+ it('rejects non-finite inputs through the shared GCD validation', () => {
101
+ expect(() => lcm(Infinity, 0)).toThrow(RangeError);
102
+ expect(() => lcm(0, NaN)).toThrow(RangeError);
103
+ });
95
104
  });
@@ -24,6 +24,13 @@ describe('createRandomSource', () => {
24
24
  expect(differs).toBe(true);
25
25
  });
26
26
 
27
+ it('pins the mulberry32 transform with a known-answer sequence', () => {
28
+ const rng = createRandomSource(0xc0ffee);
29
+ expect([rng(), rng(), rng(), rng()]).toEqual([
30
+ 0.021141508361324668, 0.6661099966149777, 0.7799714196007699, 0.7395844468846917,
31
+ ]);
32
+ });
33
+
27
34
  it('tolerates non-finite seeds without producing NaN', () => {
28
35
  const rng = createRandomSource(NaN);
29
36
  const v = rng();
@@ -16,6 +16,14 @@ import {
16
16
 
17
17
  const rng = () => createRandomSource(0xabcdef);
18
18
 
19
+ function sequenceRandom(...values: number[]): () => number {
20
+ let index = 0;
21
+ return () => {
22
+ if (index >= values.length) throw new Error('sequenceRandom exhausted');
23
+ return values[index++];
24
+ };
25
+ }
26
+
19
27
  describe('pick', () => {
20
28
  it('returns an element from the array', () => {
21
29
  const items = [1, 2, 3, 4, 5];
@@ -31,6 +39,9 @@ describe('pick', () => {
31
39
  const random = rng();
32
40
  for (let i = 0; i < 20; i++) expect(pick(random, [42])).toBe(42);
33
41
  });
42
+ it('selects the bucket named by an exact deterministic sample', () => {
43
+ expect(pick(() => 0.75, ['a', 'b', 'c', 'd'])).toBe('d');
44
+ });
34
45
  it('is deterministic for the same seed', () => {
35
46
  const items = ['a', 'b', 'c', 'd'];
36
47
  const a = rng();
@@ -60,10 +71,17 @@ describe('randomExponential', () => {
60
71
  for (let i = 0; i < n; i++) sum += randomExponential(random, 2);
61
72
  expect(sum / n).toBeCloseTo(0.5, 0);
62
73
  });
74
+ it('substitutes epsilon when the random source returns zero', () => {
75
+ expect(randomExponential(() => 0)).toBe(-Math.log(Number.EPSILON));
76
+ });
63
77
  it('throws for rate <= 0', () => {
64
78
  expect(() => randomExponential(rng(), 0)).toThrow(RangeError);
65
79
  expect(() => randomExponential(rng(), -1)).toThrow(RangeError);
66
80
  });
81
+ it('rejects non-finite rates', () => {
82
+ expect(() => randomExponential(rng(), NaN)).toThrow(RangeError);
83
+ expect(() => randomExponential(rng(), Infinity)).toThrow(RangeError);
84
+ });
67
85
  it('is deterministic for the same seed', () => {
68
86
  const a = rng();
69
87
  const b = rng();
@@ -83,6 +101,14 @@ describe('randomGaussian', () => {
83
101
  for (let i = 0; i < n; i++) sum += randomGaussian(random, 5, 1);
84
102
  expect(sum / n).toBeCloseTo(5, 0);
85
103
  });
104
+ it('substitutes epsilon when the first random sample is zero', () => {
105
+ const samples = [0, 0.25];
106
+ expect(randomGaussian(() => samples.shift()!)).toBeCloseTo(0, 10);
107
+ });
108
+ it('matches a deterministic Box–Muller vector with mean and scale', () => {
109
+ const standard = Math.sqrt(-2 * Math.log(0.5));
110
+ expect(randomGaussian(sequenceRandom(0.5, 0), 10, 2)).toBeCloseTo(10 + standard * 2, 12);
111
+ });
86
112
  it('is deterministic for the same seed', () => {
87
113
  const a = rng();
88
114
  const b = rng();
@@ -107,6 +133,16 @@ describe('randomGaussianPair', () => {
107
133
  }
108
134
  expect(sum / (n * 2)).toBeCloseTo(10, 0);
109
135
  });
136
+ it('substitutes epsilon when the first random sample is zero', () => {
137
+ const samples = [0, 0.25];
138
+ const [z0, z1] = randomGaussianPair(() => samples.shift()!);
139
+ expect(z0).toBeCloseTo(0, 10);
140
+ expect(z1).toBeCloseTo(Math.sqrt(-2 * Math.log(Number.EPSILON)), 10);
141
+ });
142
+ it('matches both values of a deterministic Box–Muller pair', () => {
143
+ const component = Math.sqrt(-2 * Math.log(0.5)) * Math.SQRT1_2;
144
+ expect(randomGaussianPair(sequenceRandom(0.5, 0.125), 3, 2)).toEqual([3 + component * 2, 3 + component * 2]);
145
+ });
110
146
  });
111
147
 
112
148
  describe('randomInsideUnitDisc', () => {
@@ -138,6 +174,11 @@ describe('randomInsideUnitDisc', () => {
138
174
  expect(outA.y).toBe(outB.y);
139
175
  }
140
176
  });
177
+ it('accepts and preserves a deterministic boundary point', () => {
178
+ const out = { x: 0, y: 0 };
179
+ randomInsideUnitDisc(sequenceRandom(1, 0.5, 0.5, 0.5), out);
180
+ expect(out).toEqual({ x: 1, y: 0 });
181
+ });
141
182
  });
142
183
 
143
184
  describe('randomInsideUnitSphere', () => {
@@ -170,6 +211,11 @@ describe('randomInsideUnitSphere', () => {
170
211
  expect(outA.z).toBe(outB.z);
171
212
  }
172
213
  });
214
+ it('accepts and preserves a deterministic boundary point', () => {
215
+ const out = { x: 0, y: 0, z: 0 };
216
+ randomInsideUnitSphere(sequenceRandom(1, 0.5, 0.5, 0.5, 0.5, 0.5), out);
217
+ expect(out).toEqual({ x: 1, y: 0, z: 0 });
218
+ });
173
219
  });
174
220
 
175
221
  describe('randomOnUnitCircle', () => {
@@ -200,6 +246,12 @@ describe('randomOnUnitCircle', () => {
200
246
  expect(outA.y).toBe(outB.y);
201
247
  }
202
248
  });
249
+ it('maps a quarter-turn sample to the top of the circle', () => {
250
+ const out = { x: 0, y: 0 };
251
+ randomOnUnitCircle(() => 0.25, out);
252
+ expect(out.x).toBeCloseTo(0, 12);
253
+ expect(out.y).toBeCloseTo(1, 12);
254
+ });
203
255
  });
204
256
 
205
257
  describe('randomOnUnitSphere', () => {
@@ -233,6 +285,18 @@ describe('randomOnUnitSphere', () => {
233
285
  expect(outA.z).toBe(outB.z);
234
286
  }
235
287
  });
288
+ it('projects a deterministic disc sample onto the sphere', () => {
289
+ const out = { x: 0, y: 0, z: 0 };
290
+ randomOnUnitSphere(sequenceRandom(0.75, 0.5), out);
291
+ expect(out.x).toBeCloseTo(Math.sqrt(3) / 2, 12);
292
+ expect(out.y).toBe(0);
293
+ expect(out.z).toBe(0.5);
294
+ });
295
+ it('rejects a disc-boundary sample before projecting', () => {
296
+ const out = { x: 0, y: 0, z: 0 };
297
+ randomOnUnitSphere(sequenceRandom(1, 0.5, 0.5, 0.5), out);
298
+ expect(out).toEqual({ x: 0, y: 0, z: 1 });
299
+ });
236
300
  });
237
301
 
238
302
  describe('randomPoisson', () => {
@@ -262,6 +326,13 @@ describe('randomPoisson', () => {
262
326
  expect(() => randomPoisson(rng(), 0)).toThrow(RangeError);
263
327
  expect(() => randomPoisson(rng(), -1)).toThrow(RangeError);
264
328
  });
329
+ it('rejects non-finite means', () => {
330
+ expect(() => randomPoisson(rng(), NaN)).toThrow(RangeError);
331
+ expect(() => randomPoisson(rng(), Infinity)).toThrow(RangeError);
332
+ });
333
+ it('stops when the product exactly reaches the limit', () => {
334
+ expect(randomPoisson(sequenceRandom(0.5, 0.5), Math.log(2))).toBe(0);
335
+ });
265
336
  it('is deterministic for the same seed', () => {
266
337
  const a = rng();
267
338
  const b = rng();
@@ -291,6 +362,12 @@ describe('randomWeighted', () => {
291
362
  expect(randomWeighted(random, [0, 10, 0])).toBe(1);
292
363
  }
293
364
  });
365
+ it('falls back to the final bucket for an out-of-range random source', () => {
366
+ expect(randomWeighted(() => 1.1, [1, 2, 7])).toBe(2);
367
+ });
368
+ it('selects the earlier bucket when the sample lands exactly on its boundary', () => {
369
+ expect(randomWeighted(() => 1 / 3, [1, 2])).toBe(0);
370
+ });
294
371
  it('is deterministic for the same seed', () => {
295
372
  const a = rng();
296
373
  const b = rng();
@@ -345,4 +422,15 @@ describe('shuffleInPlace', () => {
345
422
  shuffleInPlace(rng(), b);
346
423
  expect(a).toEqual(b);
347
424
  });
425
+ it('pins the swaps and consumes exactly one sample per Fisher–Yates step', () => {
426
+ const values = [0.75, 0.5, 0.25];
427
+ let calls = 0;
428
+ const items = ['a', 'b', 'c', 'd'];
429
+ shuffleInPlace(() => {
430
+ calls++;
431
+ return values[calls - 1];
432
+ }, items);
433
+ expect(items).toEqual(['c', 'a', 'b', 'd']);
434
+ expect(calls).toBe(3);
435
+ });
348
436
  });
@@ -19,6 +19,9 @@ describe('randomBool', () => {
19
19
  const random = rng();
20
20
  for (let i = 0; i < 10; i++) expect(randomBool(random, 0)).toBe(false);
21
21
  });
22
+ it('uses a half-open comparison at the probability boundary', () => {
23
+ expect(randomBool(() => 0.5, 0.5)).toBe(false);
24
+ });
22
25
  it('is deterministic for the same seed', () => {
23
26
  const a = rng();
24
27
  const b = rng();
@@ -44,6 +47,12 @@ describe('randomInt', () => {
44
47
  const random = rng();
45
48
  expect(() => randomInt(random, 10, 5)).toThrow(RangeError);
46
49
  });
50
+ it('can select the inclusive upper endpoint', () => {
51
+ expect(randomInt(() => 0.999999, 2, 4)).toBe(4);
52
+ });
53
+ it('rounds negative fractional bounds down', () => {
54
+ expect(randomInt(() => 0, -1.2, -0.2)).toBe(-2);
55
+ });
47
56
  it('is deterministic for the same seed', () => {
48
57
  const a = rng();
49
58
  const b = rng();
@@ -91,6 +100,9 @@ describe('randomSign', () => {
91
100
  expect(sawPositive).toBe(true);
92
101
  expect(sawNegative).toBe(true);
93
102
  });
103
+ it('selects the positive sign at the half-open boundary', () => {
104
+ expect(randomSign(() => 0.5)).toBe(1);
105
+ });
94
106
  it('is deterministic for the same seed', () => {
95
107
  const a = rng();
96
108
  const b = rng();
@@ -13,6 +13,17 @@ describe('mean', () => {
13
13
  it('handles negative values', () => {
14
14
  expect(mean([-2, 0, 2])).toBe(0);
15
15
  });
16
+ it('does not overflow when the finite mean is representable', () => {
17
+ expect(mean([Number.MAX_VALUE, Number.MAX_VALUE])).toBe(Number.MAX_VALUE);
18
+ });
19
+ it('retains a small term across cancellation', () => {
20
+ expect(mean([1, Number.EPSILON / 2, -1])).toBe(Number.EPSILON / 6);
21
+ });
22
+ it('preserves zero and non-finite propagation', () => {
23
+ expect(mean([0, 0])).toBe(0);
24
+ expect(mean([Infinity, Infinity])).toBe(Infinity);
25
+ expect(mean([Infinity, -Infinity])).toBeNaN();
26
+ });
16
27
  });
17
28
 
18
29
  describe('median', () => {
@@ -31,6 +42,17 @@ describe('median', () => {
31
42
  median(values);
32
43
  expect(values).toEqual(original);
33
44
  });
45
+ it('does not overflow when averaging identical finite middle values', () => {
46
+ expect(median([Number.MAX_VALUE, Number.MAX_VALUE])).toBe(Number.MAX_VALUE);
47
+ });
48
+ it('does not prematurely underflow when averaging subnormal middle values', () => {
49
+ expect(median([Number.MIN_VALUE * 2, Number.MIN_VALUE * 3])).toBe(Number.MIN_VALUE * 2);
50
+ });
51
+ it('averages negative and non-finite middle values without changing their semantics', () => {
52
+ expect(median([-4, -2])).toBe(-3);
53
+ expect(median([-Number.MAX_VALUE, Number.MAX_VALUE])).toBe(0);
54
+ expect(median([Infinity, Infinity])).toBe(Infinity);
55
+ });
34
56
  });
35
57
 
36
58
  describe('standardDeviation', () => {
@@ -43,6 +65,13 @@ describe('standardDeviation', () => {
43
65
  it('computes the population standard deviation', () => {
44
66
  expect(standardDeviation([2, 4, 4, 4, 5, 5, 7, 9])).toBeCloseTo(2, 5);
45
67
  });
68
+ it('returns zero for identical maximum finite values', () => {
69
+ expect(standardDeviation([Number.MAX_VALUE, Number.MAX_VALUE])).toBe(0);
70
+ });
71
+ it('handles zero and preserves non-finite propagation', () => {
72
+ expect(standardDeviation([0, 0])).toBe(0);
73
+ expect(standardDeviation([Infinity])).toBeNaN();
74
+ });
46
75
  });
47
76
 
48
77
  describe('variance', () => {
@@ -55,6 +84,16 @@ describe('variance', () => {
55
84
  it('computes the population variance', () => {
56
85
  expect(variance([2, 4, 4, 4, 5, 5, 7, 9])).toBeCloseTo(4, 5);
57
86
  });
87
+ it('returns zero for identical maximum finite values', () => {
88
+ expect(variance([Number.MAX_VALUE, Number.MAX_VALUE])).toBe(0);
89
+ });
90
+ it('compensates the sum of squared deviations', () => {
91
+ expect(variance([-1, 1_000_000_000_000, 1_000_000_000_000])).toBe(2.2222222222266665e23);
92
+ });
93
+ it('handles zero and preserves non-finite propagation', () => {
94
+ expect(variance([0, 0])).toBe(0);
95
+ expect(variance([Infinity])).toBeNaN();
96
+ });
58
97
  });
59
98
 
60
99
  describe('weightedAverage', () => {
@@ -71,4 +110,24 @@ describe('weightedAverage', () => {
71
110
  it('throws when arrays have different lengths', () => {
72
111
  expect(() => weightedAverage([1, 2], [1])).toThrow(RangeError);
73
112
  });
113
+ it('does not overflow when the finite weighted average is representable', () => {
114
+ expect(weightedAverage([Number.MAX_VALUE, Number.MAX_VALUE], [1, 1])).toBe(Number.MAX_VALUE);
115
+ });
116
+ it('uses normalized weights in the weighted product', () => {
117
+ expect(weightedAverage([2, 10], [1, 3])).toBe(8);
118
+ });
119
+ it('retains small weighted terms across cancellation', () => {
120
+ expect(weightedAverage([10_000_000_000_000_000, -1_000_000_000_000_000, -10_000_000_000_000_000], [2, 1, 1])).toBe(
121
+ 2_250_000_000_000_000,
122
+ );
123
+ });
124
+ it('handles zero values and cancelling non-zero weights', () => {
125
+ expect(weightedAverage([0, 0], [1, 1])).toBe(0);
126
+ expect(weightedAverage([1, 2], [1, -1])).toBeNaN();
127
+ });
128
+ it('preserves non-finite weighted-average propagation', () => {
129
+ expect(weightedAverage([Infinity], [1])).toBe(Infinity);
130
+ expect(weightedAverage([Infinity, 1], [1, -1])).toBeNaN();
131
+ expect(weightedAverage([1], [Infinity])).toBeNaN();
132
+ });
74
133
  });