Skip to content
78 linesCodeBlameRaw
1// Small helpers for numbers.
2/** Returns the sum of a and b. */
3function add(a, b) {
4 return a + b;
5}
6
7/** Returns the product of a and b. */
8function multiply(a, b) {
9 return a * b;
10}
11
12/** Returns the non-negative remainder of a divided by b; throws RangeError when b is 0. */
13function mod(a, b) {
14 if (b === 0) {
15 throw new RangeError("mod by zero");
16 }
17 return ((a % b) + Math.abs(b)) % Math.abs(b);
18}
19
20/** Returns a minus b. */
21function subtract(a, b) {
22 return a - b;
23}
24
25/** Returns a divided by b; throws a RangeError when b is 0. */
26function divide(a, b) {
27 if (b === 0) {
28 throw new RangeError("Division by zero");
29 }
30 return a / b;
31}
32
33/** Returns base raised to the whole-number exponent; throws a RangeError if exponent is negative. */
34function power(base, exponent) {
35 if (exponent < 0) {
36 throw new RangeError("exponent must not be negative");
37 }
38 let result = 1;
39 for (let i = 0; i < exponent; i++) {
40 result *= base;
41 }
42 return result;
43}
44
45/** Returns the average of numbers; throws a TypeError if the array is empty. */
46function mean(numbers) {
47 if (numbers.length === 0) {
48 throw new TypeError("numbers must not be empty");
49 }
50 return numbers.reduce((sum, n) => sum + n, 0) / numbers.length;
51}
52
53/** Returns the middle value of numbers (the average of the two middle values when the length is even); throws a TypeError if the array is empty. */
54function median(numbers) {
55 if (numbers.length === 0) {
56 throw new TypeError("numbers must not be empty");
57 }
58 const sorted = [...numbers].sort((a, b) => a - b);
59 const mid = Math.floor(sorted.length / 2);
60 return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
61}
62
63/** Returns the population standard deviation of numbers; throws a TypeError if the array is empty. */
64function standard_deviation(numbers) {
65 const avg = mean(numbers);
66 const variance = numbers.reduce((sum, n) => sum + (n - avg) ** 2, 0) / numbers.length;
67 return Math.sqrt(variance);
68}
69
70/** Returns value limited to the range [min, max]; throws a RangeError if min is greater than max. */
71function clamp(value, min, max) {
72 if (min > max) {
73 throw new RangeError("min must not be greater than max");
74 }
75 return Math.min(Math.max(value, min), max);
76}
77
78module.exports = { add, multiply, subtract, divide, mod, power, mean, median, standard_deviation, clamp };