]> Lady’s Gitweb - Pisces/blob - numeric.js
64d9a80502f5fc8b363d59acb5aa18d9e5e988d7
[Pisces] / numeric.js
1 // ♓🌟 Piscēs ∷ numeric.js
2 // ====================================================================
3 //
4 // Copyright © 2022 Lady [@ Lady’s Computer].
5 //
6 // This Source Code Form is subject to the terms of the Mozilla Public
7 // License, v. 2.0. If a copy of the MPL was not distributed with this
8 // file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
9
10 import { sameValue, toPrimitive } from "./value.js";
11
12 export const {
13 /**
14 * ln(10).
15 *
16 * ※ This is an alias for Math.LN10.
17 */
18 LN10,
19
20 /**
21 * ln(2).
22 *
23 * ※ This is an alias for Math.LN2.
24 */
25 LN2,
26
27 /**
28 * log10(ℇ).
29 *
30 * ※ This is an alias for Math.LOG10E.
31 */
32 LOG10E: LOG10ℇ,
33
34 /**
35 * log2(ℇ).
36 *
37 * ※ This is an alias for Math.LOG2E.
38 */
39 LOG2E: LOG2ℇ,
40
41 /**
42 * sqrt(.5).
43 *
44 * ※ This is an alias for Math.SQRT1_2.
45 */
46 SQRT1_2: RECIPROCAL_SQRT2,
47
48 /**
49 * sqrt(2).
50 *
51 * ※ This is an alias for Math.SQRT2.
52 */
53 SQRT2,
54
55 /**
56 * Returns the arccos of the provided value.
57 *
58 * ※ This is an alias for Math.acos.
59 *
60 * ☡ This function does not allow big·int arguments.
61 */
62 acos: arccos,
63
64 /**
65 * Returns the arccosh of the provided value.
66 *
67 * ※ This is an alias for Math.acosh.
68 *
69 * ☡ This function does not allow big·int arguments.
70 */
71 acosh: arccosh,
72
73 /**
74 * Returns the arcsin of the provided value.
75 *
76 * ※ This is an alias for Math.asin.
77 *
78 * ☡ This function does not allow big·int arguments.
79 */
80 asin: arcsin,
81
82 /**
83 * Returns the arcsinh of the provided value.
84 *
85 * ※ This is an alias for Math.asinh.
86 *
87 * ☡ This function does not allow big·int arguments.
88 */
89 asinh: arcsinh,
90
91 /**
92 * Returns the arctan of the provided value.
93 *
94 * ※ This is an alias for Math.atan.
95 *
96 * ☡ This function does not allow big·int arguments.
97 */
98 atan: arctan,
99
100 /**
101 * Returns the arctanh of the provided value.
102 *
103 * ※ This is an alias for Math.atanh.
104 *
105 * ☡ This function does not allow big·int arguments.
106 */
107 atanh: arctanh,
108
109 /**
110 * Returns the cube root of the provided value.
111 *
112 * ※ This is an alias for Math.cbrt.
113 *
114 * ☡ This function does not allow big·int arguments.
115 */
116 cbrt,
117
118 /**
119 * Returns the ceiling of the provided value.
120 *
121 * ※ This is an alias for Math.ceil.
122 *
123 * ☡ This function does not allow big·int arguments.
124 */
125 ceil,
126
127 /**
128 * Returns the cos of the provided value.
129 *
130 * ※ This is an alias for Math.cos.
131 *
132 * ☡ This function does not allow big·int arguments.
133 */
134 cos,
135
136 /**
137 * Returns the cosh of the provided value.
138 *
139 * ※ This is an alias for Math.cosh.
140 *
141 * ☡ This function does not allow big·int arguments.
142 */
143 cosh,
144
145 /**
146 * Returns the Euler number raised to the provided value.
147 *
148 * ※ This is an alias for Math.exp.
149 *
150 * ☡ This function does not allow big·int arguments.
151 */
152 exp,
153
154 /**
155 * Returns the Euler number raised to the provided value, minus one.
156 *
157 * ※ This is an alias for Math.expm1.
158 *
159 * ☡ This function does not allow big·int arguments.
160 */
161 expm1,
162
163 /**
164 * Returns the floor of the provided value.
165 *
166 * ※ This is an alias for Math.floor.
167 *
168 * ☡ This function does not allow big·int arguments.
169 */
170 floor,
171
172 /**
173 * Returns the square root of the sum of the squares of the provided
174 * arguments.
175 *
176 * ※ This is an alias for Math.hypot.
177 *
178 * ☡ This function does not allow big·int arguments.
179 */
180 hypot,
181
182 /**
183 * Returns the ln of the provided value.
184 *
185 * ※ This is an alias for Math.log.
186 *
187 * ☡ This function does not allow big·int arguments.
188 */
189 log: ln,
190
191 /**
192 * Returns the log10 of the provided value.
193 *
194 * ※ This is an alias for Math.log10.
195 *
196 * ☡ This function does not allow big·int arguments.
197 */
198 log10,
199
200 /**
201 * Returns the ln of one plus the provided value.
202 *
203 * ※ This is an alias for Math.log1p.
204 *
205 * ☡ This function does not allow big·int arguments.
206 */
207 log1p: ln1p,
208
209 /**
210 * Returns the log2 of the provided value.
211 *
212 * ※ This is an alias for Math.log2.
213 *
214 * ☡ This function does not allow big·int arguments.
215 */
216 log2,
217
218 /**
219 * Returns a pseudo·random value in the range [0, 1).
220 *
221 * ※ This is an alias for Math.random.
222 */
223 random: rand,
224
225 /**
226 * Returns the round of the provided value.
227 *
228 * ※ This is an alias for Math.round.
229 *
230 * ☡ This function does not allow big·int arguments.
231 */
232 round,
233
234 /**
235 * Returns the sinh of the provided value.
236 *
237 * ※ This is an alias for Math.sinh.
238 *
239 * ☡ This function does not allow big·int arguments.
240 */
241 sinh,
242
243 /**
244 * Returns the square root of the provided value.
245 *
246 * ※ This is an alias for Math.sqrt.
247 *
248 * ☡ This function does not allow big·int arguments.
249 */
250 sqrt,
251
252 /**
253 * Returns the tan of the provided value.
254 *
255 * ※ This is an alias for Math.tan.
256 *
257 * ☡ This function does not allow big·int arguments.
258 */
259 tan,
260
261 /**
262 * Returns the tanh of the provided value.
263 *
264 * ※ This is an alias for Math.tanh.
265 *
266 * ☡ This function does not allow big·int arguments.
267 */
268 tanh,
269
270 /**
271 * Returns the trunc of the provided value.
272 *
273 * ※ This is an alias for Math.trunc.
274 *
275 * ☡ This function does not allow big·int arguments.
276 */
277 trunc,
278
279 /**
280 * The mathematical constant π.
281 *
282 * ※ This is an alias for Math.PI.
283 */
284 PI: Π,
285
286 /**
287 * The Euler number.
288 *
289 * ※ This is an alias for Math.E.
290 */
291 E: ℇ,
292 } = Math;
293
294 export const {
295 /**
296 * The largest number value less than infinity.
297 *
298 * ※ This is an alias for Number.MAX_VALUE.
299 */
300 MAX_VALUE: MAXIMUM_NUMBER,
301
302 /**
303 * 2**53 - 1.
304 *
305 * ※ This is an alias for Number.MAX_SAFE_INTEGER.
306 */
307 MAX_SAFE_INTEGER: MAXIMUM_SAFE_INTEGRAL_NUMBER,
308
309 /**
310 * The smallest number value greater than negative infinity.
311 *
312 * ※ This is an alias for Number.MIN_VALUE.
313 */
314 MIN_VALUE: MINIMUM_NUMBER,
315
316 /**
317 * -(2**53 - 1).
318 *
319 * ※ This is an alias for Number.MIN_SAFE_INTEGER.
320 */
321 MIN_SAFE_INTEGER: MINIMUM_SAFE_INTEGRAL_NUMBER,
322
323 /**
324 * Negative infinity.
325 *
326 * ※ This is an alias for Number.NEGATIVE_INFINITY.
327 */
328 NEGATIVE_INFINITY,
329
330 /**
331 * Nan.
332 *
333 * ※ This is an alias for Number.NaN.
334 */
335 NaN: NAN,
336
337 /**
338 * Positive infinity.
339 *
340 * ※ This is an alias for Number.POSITIVE_INFINITY.
341 */
342 POSITIVE_INFINITY,
343
344 /**
345 * The difference between 1 and the smallest number greater than 1.
346 *
347 * ※ This is an alias for Number.EPSILON.
348 */
349 EPSILON: Ε,
350
351 /**
352 * Returns whether the provided value is a finite number.
353 *
354 * ※ This is an alias for Number.isFinite.
355 */
356 isFinite: isFiniteNumber,
357
358 /**
359 * Returns whether the provided value is an integral number.
360 *
361 * ※ This is an alias for Number.isInteger.
362 */
363 isInteger: isIntegralNumber,
364
365 /**
366 * Returns whether the provided value is nan.
367 *
368 * ※ This is an alias for Number.isNaN.
369 */
370 isNaN: isNan,
371
372 /**
373 * Returns whether the provided value is a safe integral number.
374 *
375 * ※ This is an alias for Number.isSafeInteger.
376 */
377 isSafeInteger: isSafeIntegralNumber,
378 } = Number;
379
380 /** Positive zero. */
381 export const POSITIVE_ZERO = 0;
382
383 /** Negative zero. */
384 export const NEGATIVE_ZERO = -0;
385
386 /**
387 * Returns the magnitude (absolute value) of the provided value.
388 *
389 * ※ Unlike Math.abs, this function can take big·int arguments.
390 */
391 export const abs = ($) => {
392 const n = toNumeric($);
393 return typeof n === "bigint"
394 ? n < 0n ? -n : n
395 : isNan(n)
396 ? NAN
397 : sameValue(n, -0)
398 ? 0
399 : sameValue(n, NEGATIVE_INFINITY)
400 ? POSITIVE_INFINITY
401 : n < 0
402 ? -n
403 : n;
404 };
405
406 export const {
407 /**
408 * Returns the arctangent of the dividend of the provided values.
409 *
410 * ※ Unlike Math.atan2, this function can take big·int arguments.
411 * However, the result will always be a number.
412 */
413 atan2,
414
415 /**
416 * Returns the number of leading zeroes in the 32‐bit representation of
417 * the provided value.
418 *
419 * ※ Unlike Math.clz32, this function accepts either number or big·int
420 * values.
421 */
422 clz32,
423
424 /**
425 * Returns the 32‐bit float which best approximate the provided
426 * value.
427 *
428 * ※ Unlike Math.fround, this function can take big·int arguments.
429 * However, the result will always be a number.
430 */
431 toFloat32,
432 } = (() => {
433 const { atan2, fround, clz32 } = Math;
434 return {
435 atan2: (y, x) => atan2(toNumber(y), toNumber(x)),
436 clz32: ($) => {
437 const n = toNumeric($);
438 return clz32(
439 typeof n === "bigint" ? toNumber(toUintN(32, n)) : n,
440 );
441 },
442 toFloat32: ($) => fround(toNumber($)),
443 };
444 })();
445
446 /**
447 * Returns the highest value of the provided arguments, or negative
448 * infinity if no argument is provided.
449 *
450 * ※ Unlike Math.max, this function accepts either number or big·int
451 * values. All values must be of the same type, or this function will
452 * throw an error.
453 *
454 * ☡ If no argument is supplied, the result will be a number, not a
455 * big·int.
456 */
457 export const max = (...$s) => {
458 let highest = undefined;
459 for (let i = 0; i < $s.length; ++i) {
460 // Iterate over all the numbers.
461 const number = toNumeric($s[i]);
462 if (highest === undefined) {
463 // The current number is the first one.
464 if (isNan(number)) {
465 // The current number is nan.
466 return NAN;
467 } else {
468 // The current number is not nan.
469 highest = number;
470 }
471 } else {
472 if (typeof highest !== typeof number) {
473 // The type of the current number and the lowest number don’t
474 // match.
475 throw new TypeError("Piscēs: Type mismatch.");
476 } else if (isNan(number)) {
477 // The current number is nan.
478 return NAN;
479 } else if (sameValue(number, 0) && sameValue(highest, -0)) {
480 // The current number is +0 and the highest number is -0.
481 highest = 0;
482 } else if (highest === undefined || number > highest) {
483 // The current number is greater than the highest number.
484 highest = number;
485 } else {
486 // The current number is less than or equal to the lowest
487 // number.
488 /* do nothing */
489 }
490 }
491 }
492 return highest ?? NEGATIVE_INFINITY;
493 };
494
495 /**
496 * Returns the lowest value of the provided arguments, or positive
497 * infinity if no argument is provided.
498 *
499 * ※ Unlike Math.min, this function accepts either number or big·int
500 * values. All values must be of the same type, or this function will
501 * throw an error.
502 *
503 * ☡ If no argument is supplied, the result will be a number, not a
504 * big·int.
505 */
506 export const min = (...$s) => {
507 let lowest = undefined;
508 for (let i = 0; i < $s.length; ++i) {
509 // Iterate over all the numbers.
510 const number = toNumeric($s[i]);
511 if (lowest === undefined) {
512 // The current number is the first one.
513 if (isNan(number)) {
514 // The current number is nan.
515 return NAN;
516 } else {
517 // The current number is not nan.
518 lowest = number;
519 }
520 } else {
521 // The current number is not the first one.
522 if (typeof lowest !== typeof number) {
523 // The type of the current number and the lowest number don’t
524 // match.
525 throw new TypeError("Piscēs: Type mismatch.");
526 } else if (isNan(number)) {
527 // The current number is nan.
528 return NAN;
529 } else if (sameValue(number, -0) && sameValue(lowest, 0)) {
530 // The current number is -0 and the lowest number is +0.
531 lowest = -0;
532 } else if (number < lowest) {
533 // The current number is less than the lowest number.
534 lowest = number;
535 } else {
536 // The current number is greater than or equal to the lowest
537 // number.
538 /* do nothing */
539 }
540 }
541 }
542 return lowest ?? POSITIVE_INFINITY;
543 };
544
545 /**
546 * Returns a unit value with the same sign as the provided value, or
547 * the provided value itself if it is not a number or (potentially
548 * signed) zero.
549 *
550 * For big·ints, the return value of this function is 0n if the
551 * provided value is 0n, -1n if the provided value is negative, and +1n
552 * otherwise.
553 *
554 * For numbers, the return value is nan, -0, or +0 if the provided
555 * value is nan, -0, or +0, respectively, and -1 if the provided value
556 * is negative and +1 if the provided value is positive otherwise. Note
557 * that positive and negative infinity will return +1 and -1
558 * respectively.
559 *
560 * ※ Unlike Math.sign, this function accepts either number or big·int
561 * values.
562 */
563 export const sgn = ($) => {
564 const n = toNumeric($);
565 return typeof n === "bigint"
566 ? n === 0n ? 0n : n < 0n ? -1n : 1n
567 : isNan(n) || n === 0
568 ? n
569 //deno-lint-ignore no-compare-neg-zero
570 : n < -0
571 ? -1
572 : 1;
573 };
574
575 /**
576 * Returns the result of converting the provided value to a big·int.
577 *
578 * ※ This method is safe to use with numbers.
579 *
580 * ※ This is effectively an alias for BigInt.
581 */
582 export const { toBigInt } = (() => {
583 const makeBigInt = BigInt;
584 return { toBigInt: ($) => makeBigInt($) };
585 })();
586
587 export const {
588 /**
589 * Returns the result of converting the provided value to fit within
590 * the provided number of bits as a signed integer.
591 *
592 * ※ Unlike BigInt.asIntN, this function accepts both big·int and
593 * number values.
594 *
595 * ☡ The first argument, the number of bits, must be a number.
596 */
597 toIntN,
598
599 /**
600 * Returns the result of converting the provided value to fit within
601 * the provided number of bits as an unsigned integer.
602 *
603 * ※ Unlike BigInt.asUintN, this function accepts both big·int and
604 * number values.
605 *
606 * ☡ The first argument, the number of bits, must be a number.
607 */
608 toUintN,
609 } = (() => {
610 const { asIntN, asUintN } = BigInt;
611 return {
612 toIntN: (n, $) => {
613 const prim = toPrimitive($);
614 if (typeof prim === "bigint") {
615 // The primitive value is a big·int.
616 return asIntN(n, prim);
617 } else {
618 // The primitive value is not a big·int.
619 const int = trunc(prim);
620 if (!isFiniteNumber(int) || int == 0) {
621 // The truncated value is zero or not finite.
622 return 0;
623 } else {
624 // The truncated value is finite.
625 return toNumber(asIntN(n, toBigInt(int)));
626 }
627 }
628 },
629 toUintN: (n, $) => {
630 const prim = toPrimitive($);
631 if (typeof prim === "bigint") {
632 // The primitive value is a big·int.
633 return asUintN(n, prim);
634 } else {
635 // The primitive value is not a big·int.
636 const int = trunc(prim);
637 if (!isFiniteNumber(int) || int == 0) {
638 // The truncated value is zero or not finite.
639 return 0;
640 } else {
641 // The truncated value is finite.
642 return toNumber(asUintN(n, toBigInt(int)));
643 }
644 }
645 },
646 };
647 })();
648
649 /**
650 * Returns the result of converting the provided number to an integer
651 * or infinity.
652 *
653 * ※ This function will never return negative zero.
654 */
655 export const toIntegerOrInfinity = ($) => {
656 const integer = trunc(toNumber($));
657 if (isNan(integer) || integer == 0) {
658 // The provided value truncs to nan or (positive or negative) zero.
659 return 0;
660 } else if (integer == POSITIVE_INFINITY) {
661 // The provided value truncs to positive infinity.
662 return POSITIVE_INFINITY;
663 } else if (integer == NEGATIVE_INFINITY) {
664 // The provided value truncs to negative infinity.
665 return NEGATIVE_INFINITY;
666 } else {
667 // The provided value truncs to an integer.
668 return integer;
669 }
670 };
671
672 /**
673 * Returns the result of converting the provided number to an integral
674 * number.
675 *
676 * ※ This function will never return negative zero.
677 */
678 export const toIntegralNumber = ($) => {
679 const n = toIntegerOrInfinity($);
680 return !isFiniteNumber(n) || n == 0 ? 0 : n;
681 };
682
683 /**
684 * Returns the result of converting the provided value to a number.
685 *
686 * ※ This method is safe to use with big·ints.
687 *
688 * ※ This is effectively a nonconstructible version of the Number
689 * constructor.
690 */
691 export const { toNumber } = (() => {
692 const makeNumber = Number;
693 return { toNumber: ($) => makeNumber($) };
694 })();
695
696 /**
697 * Returns the result of converting the provided value to a number or
698 * big·int.
699 *
700 * ※ If the result of converting the provided value to a primitive is
701 * not a big·int, this function will return a number.
702 */
703 export const toNumeric = ($) => {
704 const primValue = toPrimitive($, "number");
705 return typeof primValue === "bigint" ? primValue : +primValue;
706 };
This page took 0.092722 seconds and 3 git commands to generate.