This is project implements all of the Math.*
functions in JavaScript without
using the built-in Math
object. For what reason would I do such a thing? Well,
that remains to be seen.
I cannot guarantee the accuracy of all of these functions. I can guarantee the accuracy of the constants and the guards, however.
If you find an issue with the logic behind any of the functions, please open an issue so that I can address it promptly. Thanks!
deno add @nick/math
bunx jsr add @nick/math
pnpm dlx jsr add @nick/math
npx jsr add @nick/math
yarn dlx jsr add @nick/math
import * as math from "@nick/math";
console.assert(math.abs(-1) === 1);
console.assert(math.acos(0.5) === 1.0471975511965979);
console.assert(math.acosh(1) === 0);
console.assert(math.log(9) === 2.1972245773362196);
console.assert(math.PI === 3.141592653589793);
import { abs } from "@nick/math/abs";
import { fround } from "@nick/math/fround";
import { log } from "@nick/math/log";
Table of Contents
- Constants
E
(Euler's number)LN10
(Natural logarithm of 10)LN2
(Natural logarithm of 2)LOG2E
(Base 2 logarithm of E)LOG10E
(Base 10 logarithm of E)PI
(π)SQRT1_2
(Square root of 1/2)SQRT2
(Square root of 2)EPSILON
MAX_SAFE_INTEGER
MIN_SAFE_INTEGER
MAX_VALUE
MIN_VALUE
NEGATIVE_INFINITY
POSITIVE_INFINITY
NAN
- Functions
- Guards
import { E } from "@nick/math/constants/e";
console.assert(E === 2.718281828459045);
import { E } from "@nick/math/constants/e";
function assertEulersNumber(e: number): asserts e is E {
if (e !== E) throw new TypeError(`Expected ${E}, got ${e}`);
}
import { LN10 } from "@nick/math/constants/ln10";
console.assert(LN10 === 2.302585092994046);
import { LN10 } from "@nick/math/constants/ln10";
function assertNaturalLogarithmOf10(ln10: number): asserts ln10 is LN10 {
if (ln10 !== LN10) throw new TypeError(`Expected ${LN10}, got ${ln10}`);
}
import { LN2 } from "@nick/math/constants/ln2";
console.assert(LN2 === 0.6931471805599453);
import { LN2 } from "@nick/math/constants/ln2";
function assertNaturalLogarithmOf2(ln2: number): asserts ln2 is LN2 {
if (ln2 !== LN2) throw new TypeError(`Expected ${LN2}, got ${ln2}`);
}
import { LOG2E } from "@nick/math/constants/log2e";
console.assert(LOG2E === 1.4426950408889634);
import { LOG2E } from "@nick/math/constants/log2e";
function assertBase2LogarithmOfE(log2e: number): asserts log2e is LOG2E {
if (log2e !== LOG2E) throw new TypeError(`Expected ${LOG2E}, got ${log2e}`);
}
import { LOG10E } from "@nick/math/constants/log10e";
console.assert(LOG10E === 0.4342944819032518);
import { LOG10E } from "@nick/math/constants/log10e";
function assertBase10LogarithmOfE(log10e: number): asserts log10e is LOG10E {
if (log10e !== LOG10E) {
throw new TypeError(`Expected ${LOG10E}, got ${log10e}`);
}
}
import { PI } from "@nick/math/constants/pi";
console.assert(PI === 3.141592653589793);
import { PI } from "@nick/math/constants/pi";
function assertPi(pi: number): asserts pi is PI {
if (pi !== PI) throw new TypeError(`Expected ${PI}, got ${pi}`);
}
import { SQRT1_2 } from "@nick/math/constants/sqrt1_2";
console.assert(SQRT1_2 === 0.7071067811865476);
import { SQRT1_2 } from "@nick/math/constants/sqrt1_2";
function assertSquareRootOfOneHalf(
sqrt1_2: number,
): asserts sqrt1_2 is SQRT1_2 {
if (sqrt1_2 !== SQRT1_2) {
throw new TypeError(`Expected ${SQRT1_2}, got ${sqrt1_2}`);
}
}
import { SQRT2 } from "@nick/math/constants/sqrt2";
console.assert(SQRT2 === 1.4142135623730951);
import { SQRT2 } from "@nick/math/constants/sqrt2";
function assertSquareRootOfTwo(sqrt2: number): asserts sqrt2 is SQRT2 {
if (sqrt2 !== SQRT2) throw new TypeError(`Expected ${SQRT2}, got ${sqrt2}`);
}
Represents the smallest positive number that can be added to 1
to get a result
different from 1
.
import { EPSILON } from "@nick/math/constants/epsilon";
console.assert(EPSILON === 2.220446049250313e-16);
import { EPSILON } from "@nick/math/constants/epsilon";
function assertEpsilon(epsilon: number): asserts epsilon is EPSILON {
if (epsilon !== EPSILON) {
throw new TypeError(`Expected ${EPSILON}, got ${epsilon}`);
}
}
The maximum safe integer in JavaScript, 2^53 - 1
.
import { MAX_SAFE_INTEGER } from "@nick/math/constants/max-safe-integer";
console.assert(MAX_SAFE_INTEGER === 9007199254740991);
import { MAX_SAFE_INTEGER } from "@nick/math/constants/max-safe-integer";
function assertMaxSafeInteger(
maxSafeInteger: number,
): asserts maxSafeInteger is MAX_SAFE_INTEGER {
if (maxSafeInteger !== MAX_SAFE_INTEGER) {
throw new TypeError(`Expected ${MAX_SAFE_INTEGER}, got ${maxSafeInteger}`);
}
}
The minimum safe integer in JavaScript, -2^53 + 1
.
import { MIN_SAFE_INTEGER } from "@nick/math/constants/min-safe-integer";
console.assert(MIN_SAFE_INTEGER === -9007199254740991);
import { MIN_SAFE_INTEGER } from "@nick/math/constants/min-safe-integer";
function assertMinSafeInteger(
minSafeInteger: number,
): asserts minSafeInteger is MIN_SAFE_INTEGER {
if (minSafeInteger !== MIN_SAFE_INTEGER) {
throw new TypeError(`Expected ${MIN_SAFE_INTEGER}, got ${minSafeInteger}`);
}
}
The maximum representable value in JavaScript.
import { MAX_VALUE } from "@nick/math/constants/max-value";
console.assert(MAX_VALUE === 1.7976931348623157e308);
import { MAX_VALUE } from "@nick/math/constants/max-value";
function assertMaxValue(maxValue: number): asserts maxValue is MAX_VALUE {
if (maxValue !== MAX_VALUE) {
throw new TypeError(`Expected ${MAX_VALUE}, got ${maxValue}`);
}
}
The minimum representable value in JavaScript.
import { MIN_VALUE } from "@nick/math/constants/min-value";
console.assert(MIN_VALUE === 5e-324);
import { MIN_VALUE } from "@nick/math/constants/min-value";
function assertMinValue(minValue: number): asserts minValue is MIN_VALUE {
if (minValue !== MIN_VALUE) {
throw new TypeError(`Expected ${MIN_VALUE}, got ${minValue}`);
}
}
The negative infinity value in JavaScript.
import { NEGATIVE_INFINITY } from "@nick/math/constants/negative-infinity";
console.assert(NEGATIVE_INFINITY === -Infinity);
import { NEGATIVE_INFINITY } from "@nick/math/constants/negative-infinity";
function assertNegativeInfinity(
negativeInfinity: number,
): asserts negativeInfinity is NEGATIVE_INFINITY {
if (negativeInfinity !== NEGATIVE_INFINITY) {
throw new TypeError(
`Expected ${NEGATIVE_INFINITY}, got ${negativeInfinity}`,
);
}
}
The positive infinity value in JavaScript.
import { POSITIVE_INFINITY } from "@nick/math/constants/positive-infinity";
console.assert(POSITIVE_INFINITY === Infinity);
import { POSITIVE_INFINITY } from "@nick/math/constants/positive-infinity";
function assertPositiveInfinity(
positiveInfinity: number,
): asserts positiveInfinity is POSITIVE_INFINITY {
if (positiveInfinity !== POSITIVE_INFINITY) {
throw new TypeError(
`Expected ${POSITIVE_INFINITY}, got ${positiveInfinity}`,
);
}
}
The NaN
value in JavaScript, representing "Not a Number".
import { NAN } from "@nick/math/constants/nan";
console.log(NAN); // NaN
// or, to use the same name as the global constant:
import { NaN } from "@nick/math/constants/nan";
console.log(NaN); // NaN
import { NaN } from "@nick/math/constants/nan";
function assertNaN(nan: number): asserts nan is NaN {
if (nan !== nan) throw new TypeError(`Expected ${NaN}, got ${nan}`);
}
Returns the absolute value of a number.
import { abs } from "@nick/math/abs";
console.assert(abs(-1) === 1);
Returns the arccosine of a number.
import { acos } from "@nick/math/acos";
console.assert(acos(0.5) === 1.0471975511965979);
Returns the inverse hyperbolic cosine of a number.
import { acosh } from "@nick/math/acosh";
console.assert(acosh(1) === 0);
Returns the arcsine of a number.
import { asin } from "@nick/math/asin";
console.assert(asin(0.5) === 0.5235987755982989);
Returns the inverse hyperbolic sine of a number.
import { asinh } from "@nick/math/asinh";
console.assert(asinh(0.5) === 0.48121182505960347);
Returns the arctangent of a number.
import { atan } from "@nick/math/atan";
console.assert(atan(0.5) === 0.4636476090008061);
Returns the arctangent of the quotient of its arguments.
import { atan2 } from "@nick/math/atan2";
console.assert(atan2(1, 1) === 0.7853981633974483);
Returns the inverse hyperbolic tangent of a number.
import { atanh } from "@nick/math/atanh";
console.assert(atanh(0.5) === 0.5493061443340549);
Returns the cube root of a number.
import { cbrt } from "@nick/math/cbrt";
console.assert(cbrt(27) === 3);
Returns the smallest integer greater than or equal to a number.
import { ceil } from "@nick/math/ceil";
console.assert(ceil(1.5) === 2);
Returns the number of leading zero bits in the 32-bit binary representation of a number.
import { clz32 } from "@nick/math/clz32";
console.assert(clz32(1) === 31);
Returns the cosine of a number.
import { cos } from "@nick/math/cos";
console.assert(cos(0.5) === 0.8775825618903728);
Returns the hyperbolic cosine of a number.
import { cosh } from "@nick/math/cosh";
console.assert(cosh(0.5) === 1.1276259652063807);
Returns E
raised to the power of a number.
import { exp } from "@nick/math/exp";
console.assert(exp(1) === 2.718281828459045);
Returns E
raised to the power of a number, minus 1
.
import { expm1 } from "@nick/math/expm1";
console.assert(expm1(1) === 1.718281828459045);
Returns the largest integer less than or equal to a number.
import { floor } from "@nick/math/floor";
console.assert(floor(1.5) === 1);
Returns the nearest single precision float representation of a number.
import { fround } from "@nick/math/fround";
import { PI } from "@nick/math/constants/pi";
console.log(PI, "->", fround(PI));
// 3.141592653589793 -> 3.1415927410125732
Returns the nearest 16-bit float representation of a number, as per the IEEE 754 standard. Introduced by the TC39 Proposal for Float16Array.
import { f16round } from "@nick/math/f16round";
import { PI } from "@nick/math/constants/pi";
console.assert(f16round(PI) === 3.140625);
Returns the square root of the sum of the squares of its arguments.
import { hypot } from "@nick/math/hypot";
console.assert(hypot(3, 4) === 5);
Returns the result of a 32-bit integer multiplication.
import { imul } from "@nick/math/imul";
console.assert(imul(2, 3) === 6);
Returns the natural logarithm of a number.
import { log } from "@nick/math/log";
console.assert(log(9) === 2.1972245773362196);
Returns the natural logarithm of 1
plus a number.
import { log1p } from "@nick/math/log1p";
console.assert(log1p(9) === 2.302585092994046);
Returns the base 10 logarithm of a number.
import { log10 } from "@nick/math/log10";
console.assert(log10(100) === 2);
Returns the base 2 logarithm of a number.
import { log2 } from "@nick/math/log2";
console.assert(log2(8) === 3);
Returns the largest of zero or more numbers.
import { max } from "@nick/math/max";
console.assert(max(1, 2, 3) === 3);
Returns the smallest of zero or more numbers.
import { min } from "@nick/math/min";
console.assert(min(1, 2, 3) === 1);
Returns the base to the exponent power.
import { pow } from "@nick/math/pow";
console.assert(pow(2, 3) === 8);
Returns a pseudo-random number between 0
and 1
.
import { random } from "@nick/math/random";
console.assert(random() >= 0 && random() < 1);
Returns the value of a number rounded to the nearest integer.
import { round } from "@nick/math/round";
console.assert(round(1.5) === 2);
Returns the sign of a number, indicating whether it is positive, negative, or zero.
import { sign } from "@nick/math/sign";
console.assert(sign(-1) === -1);
Returns the sine of a number.
import { sin } from "@nick/math/sin";
console.assert(sin(0.5) === 0.479425538604203);
Returns the hyperbolic sine of a number.
import { sinh } from "@nick/math/sinh";
console.assert(sinh(0.5) === 0.5210953054937474);
Returns the square root of a number.
import { sqrt } from "@nick/math/sqrt";
console.assert(sqrt(9) === 3);
Returns the tangent of a number.
import { tan } from "@nick/math/tan";
console.assert(tan(0.5) === 0.5463024898437905);
Returns the hyperbolic tangent of a number.
import { tanh } from "@nick/math/tanh";
console.assert(tanh(0.5) === 0.46211715726000974);
Returns the integer part of a number by removing any fractional digits.
import { trunc } from "@nick/math/trunc";
console.assert(trunc(1.5) === 1);
Determines whether a number is finite.
import { isFinite } from "@nick/math/is/finite";
console.assert(isFinite(1));
Determines whether a number is an integer.
import { isInteger } from "@nick/math/is/integer";
console.assert(isInteger(1));
Determines whether a value is NaN
.
import { isNaN } from "@nick/math/is/nan";
console.assert(isNaN(NaN));
Determines whether a number is a safe integer.
import { isSafeInteger } from "@nick/math/is/safe-integer";
console.assert(isSafeInteger(1));
Determines whether a number is -0
.
import { isNegativeZero } from "@nick/math/is/negative-zero";
console.assert(isNegativeZero(-0));
console.assert(!isNegativeZero(0));
Determines whether a number is positive infinity.
import { isPositiveInfinity } from "@nick/math/is/positive-infinity";
console.assert(isPositiveInfinity(Infinity));
Determines whether a number is negative infinity.
import { isNegativeInfinity } from "@nick/math/is/negative-infinity";
console.assert(isNegativeInfinity(-Infinity));