1 // ♓🌟 Piscēs ∷ numeric.js
2 // ====================================================================
4 // Copyright © 2022 Lady [@ Lady’s Computer].
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/>.
10 import { sameValue
, toPrimitive
} from "./value.js";
16 * ※ This is an alias for Math.LN10.
23 * ※ This is an alias for Math.LN2.
30 * ※ This is an alias for Math.LOG10E.
37 * ※ This is an alias for Math.LOG2E.
44 * ※ This is an alias for Math.SQRT1_2.
46 SQRT1_2
: RECIPROCAL_SQRT2
,
51 * ※ This is an alias for Math.SQRT2.
56 * Returns the arccos of the provided value.
58 * ※ This is an alias for Math.acos.
60 * ☡ This function does not allow big·int arguments.
65 * Returns the arccosh of the provided value.
67 * ※ This is an alias for Math.acosh.
69 * ☡ This function does not allow big·int arguments.
74 * Returns the arcsin of the provided value.
76 * ※ This is an alias for Math.asin.
78 * ☡ This function does not allow big·int arguments.
83 * Returns the arcsinh of the provided value.
85 * ※ This is an alias for Math.asinh.
87 * ☡ This function does not allow big·int arguments.
92 * Returns the arctan of the provided value.
94 * ※ This is an alias for Math.atan.
96 * ☡ This function does not allow big·int arguments.
101 * Returns the arctanh of the provided value.
103 * ※ This is an alias for Math.atanh.
105 * ☡ This function does not allow big·int arguments.
110 * Returns the cube root of the provided value.
112 * ※ This is an alias for Math.cbrt.
114 * ☡ This function does not allow big·int arguments.
119 * Returns the ceiling of the provided value.
121 * ※ This is an alias for Math.ceil.
123 * ☡ This function does not allow big·int arguments.
128 * Returns the cos of the provided value.
130 * ※ This is an alias for Math.cos.
132 * ☡ This function does not allow big·int arguments.
137 * Returns the cosh of the provided value.
139 * ※ This is an alias for Math.cosh.
141 * ☡ This function does not allow big·int arguments.
146 * Returns the Euler number raised to the provided value.
148 * ※ This is an alias for Math.exp.
150 * ☡ This function does not allow big·int arguments.
155 * Returns the Euler number raised to the provided value, minus one.
157 * ※ This is an alias for Math.expm1.
159 * ☡ This function does not allow big·int arguments.
164 * Returns the floor of the provided value.
166 * ※ This is an alias for Math.floor.
168 * ☡ This function does not allow big·int arguments.
173 * Returns the square root of the sum of the squares of the provided
176 * ※ This is an alias for Math.hypot.
178 * ☡ This function does not allow big·int arguments.
183 * Returns the ln of the provided value.
185 * ※ This is an alias for Math.log.
187 * ☡ This function does not allow big·int arguments.
192 * Returns the log10 of the provided value.
194 * ※ This is an alias for Math.log10.
196 * ☡ This function does not allow big·int arguments.
201 * Returns the ln of one plus the provided value.
203 * ※ This is an alias for Math.log1p.
205 * ☡ This function does not allow big·int arguments.
210 * Returns the log2 of the provided value.
212 * ※ This is an alias for Math.log2.
214 * ☡ This function does not allow big·int arguments.
219 * Returns a pseudo·random value in the range [0, 1).
221 * ※ This is an alias for Math.random.
226 * Returns the round of the provided value.
228 * ※ This is an alias for Math.round.
230 * ☡ This function does not allow big·int arguments.
235 * Returns the sinh of the provided value.
237 * ※ This is an alias for Math.sinh.
239 * ☡ This function does not allow big·int arguments.
244 * Returns the square root of the provided value.
246 * ※ This is an alias for Math.sqrt.
248 * ☡ This function does not allow big·int arguments.
253 * Returns the tan of the provided value.
255 * ※ This is an alias for Math.tan.
257 * ☡ This function does not allow big·int arguments.
262 * Returns the tanh of the provided value.
264 * ※ This is an alias for Math.tanh.
266 * ☡ This function does not allow big·int arguments.
271 * Returns the trunc of the provided value.
273 * ※ This is an alias for Math.trunc.
275 * ☡ This function does not allow big·int arguments.
280 * The mathematical constant π.
282 * ※ This is an alias for Math.PI.
289 * ※ This is an alias for Math.E.
296 * The largest number value less than infinity.
298 * ※ This is an alias for Number.MAX_VALUE.
300 MAX_VALUE
: MAXIMUM_NUMBER
,
305 * ※ This is an alias for Number.MAX_SAFE_INTEGER.
307 MAX_SAFE_INTEGER
: MAXIMUM_SAFE_INTEGRAL_NUMBER
,
310 * The smallest number value greater than negative infinity.
312 * ※ This is an alias for Number.MIN_VALUE.
314 MIN_VALUE
: MINIMUM_NUMBER
,
319 * ※ This is an alias for Number.MIN_SAFE_INTEGER.
321 MIN_SAFE_INTEGER
: MINIMUM_SAFE_INTEGRAL_NUMBER
,
326 * ※ This is an alias for Number.NEGATIVE_INFINITY.
333 * ※ This is an alias for Number.NaN.
340 * ※ This is an alias for Number.POSITIVE_INFINITY.
345 * The difference between 1 and the smallest number greater than 1.
347 * ※ This is an alias for Number.EPSILON.
352 * Returns whether the provided value is a finite number.
354 * ※ This is an alias for Number.isFinite.
356 isFinite
: isFiniteNumber
,
359 * Returns whether the provided value is an integral number.
361 * ※ This is an alias for Number.isInteger.
363 isInteger
: isIntegralNumber
,
366 * Returns whether the provided value is nan.
368 * ※ This is an alias for Number.isNaN.
373 * Returns whether the provided value is a safe integral number.
375 * ※ This is an alias for Number.isSafeInteger.
377 isSafeInteger
: isSafeIntegralNumber
,
380 /** Positive zero. */
381 export const POSITIVE_ZERO
= 0;
383 /** Negative zero. */
384 export const NEGATIVE_ZERO
= -0;
387 * Returns the magnitude (absolute value) of the provided value.
389 * ※ Unlike Math.abs, this function can take big·int arguments.
391 export const abs
= ($) => {
392 const n
= toNumeric($);
393 return typeof n
=== "bigint"
399 : sameValue(n
, NEGATIVE_INFINITY
)
408 * Returns the arctangent of the dividend of the provided values.
410 * ※ Unlike Math.atan2, this function can take big·int arguments.
411 * However, the result will always be a number.
416 * Returns the number of leading zeroes in the 32‐bit representation of
417 * the provided value.
419 * ※ Unlike Math.clz32, this function accepts either number or big·int
425 * Returns the 32‐bit float which best approximate the provided
428 * ※ Unlike Math.fround, this function can take big·int arguments.
429 * However, the result will always be a number.
433 const { atan2
, fround
, clz32
} = Math
;
435 atan2
: (y
, x
) => atan2(toNumber(y
), toNumber(x
)),
437 const n
= toNumeric($);
439 typeof n
=== "bigint" ? toNumber(toUintN(32, n
)) : n
,
442 toFloat32
: ($) => fround(toNumber($)),
447 * Returns the highest value of the provided arguments, or negative
448 * infinity if no argument is provided.
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
454 * ☡ If no argument is supplied, the result will be a number, not a
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.
465 // The current number is nan.
468 // The current number is not nan.
472 if (typeof highest
!== typeof number
) {
473 // The type of the current number and the lowest number don’t
475 throw new TypeError("Piscēs: Type mismatch.");
476 } else if (isNan(number
)) {
477 // The current number is nan.
479 } else if (sameValue(number
, 0) && sameValue(highest
, -0)) {
480 // The current number is +0 and the highest number is -0.
482 } else if (highest
=== undefined || number
> highest
) {
483 // The current number is greater than the highest number.
486 // The current number is less than or equal to the lowest
492 return highest
?? NEGATIVE_INFINITY
;
496 * Returns the lowest value of the provided arguments, or positive
497 * infinity if no argument is provided.
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
503 * ☡ If no argument is supplied, the result will be a number, not a
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.
514 // The current number is nan.
517 // The current number is not nan.
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
525 throw new TypeError("Piscēs: Type mismatch.");
526 } else if (isNan(number
)) {
527 // The current number is nan.
529 } else if (sameValue(number
, -0) && sameValue(lowest
, 0)) {
530 // The current number is -0 and the lowest number is +0.
532 } else if (number
< lowest
) {
533 // The current number is less than the lowest number.
536 // The current number is greater than or equal to the lowest
542 return lowest
?? POSITIVE_INFINITY
;
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
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
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
560 * ※ Unlike Math.sign, this function accepts either number or big·int
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
569 //deno-lint-ignore no-compare-neg-zero
576 * Returns the result of converting the provided value to a big·int.
578 * ※ This method is safe to use with numbers.
580 * ※ This is effectively an alias for BigInt.
582 export const { toBigInt
} = (() => {
583 const makeBigInt
= BigInt
;
584 return { toBigInt
: ($) => makeBigInt($) };
589 * Returns the result of converting the provided value to fit within
590 * the provided number of bits as a signed integer.
592 * ※ Unlike BigInt.asIntN, this function accepts both big·int and
595 * ☡ The first argument, the number of bits, must be a number.
600 * Returns the result of converting the provided value to fit within
601 * the provided number of bits as an unsigned integer.
603 * ※ Unlike BigInt.asUintN, this function accepts both big·int and
606 * ☡ The first argument, the number of bits, must be a number.
610 const { asIntN
, asUintN
} = BigInt
;
613 const prim
= toPrimitive($);
614 if (typeof prim
=== "bigint") {
615 // The primitive value is a big·int.
616 return asIntN(n
, prim
);
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.
624 // The truncated value is finite.
625 return toNumber(asIntN(n
, toBigInt(int)));
630 const prim
= toPrimitive($);
631 if (typeof prim
=== "bigint") {
632 // The primitive value is a big·int.
633 return asUintN(n
, prim
);
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.
641 // The truncated value is finite.
642 return toNumber(asUintN(n
, toBigInt(int)));
650 * Returns the result of converting the provided number to an integral
653 * ※ This function will never return negative zero.
655 export const toIntegralNumber
= ($) => {
656 const n
= toIntegralNumberOrInfinity($);
657 return !isFiniteNumber(n
) || n
== 0 ? 0 : n
;
661 * Returns the result of converting the provided number to an integer
664 * ※ Unlike the ToIntegerOrInfinity function defined in the Ecmascript
665 * specification, this function is safe to use with big·ints. However,
666 * the result will always be a number.
668 * ※ This function will never return negative zero.
670 export const toIntegralNumberOrInfinity
= ($) => {
671 const integer
= trunc(toNumber($));
672 if (isNan(integer
) || integer
== 0) {
673 // The provided value truncs to nan or (positive or negative) zero.
675 } else if (integer
== POSITIVE_INFINITY
) {
676 // The provided value truncs to positive infinity.
677 return POSITIVE_INFINITY
;
678 } else if (integer
== NEGATIVE_INFINITY
) {
679 // The provided value truncs to negative infinity.
680 return NEGATIVE_INFINITY
;
682 // The provided value truncs to an integer.
688 * Returns the result of converting the provided value to a number.
690 * ※ This method is safe to use with big·ints.
692 * ※ This is effectively a nonconstructible version of the Number
695 export const { toNumber
} = (() => {
696 const makeNumber
= Number
;
697 return { toNumber
: ($) => makeNumber($) };
701 * Returns the result of converting the provided value to a number or
704 * ※ If the result of converting the provided value to a primitive is
705 * not a big·int, this function will return a number.
707 export const toNumeric
= ($) => {
708 const primValue
= toPrimitive($, "number");
709 return typeof primValue
=== "bigint" ? primValue
: +primValue
;