All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.javascript.jscomp.js.es6.math.js Maven / Gradle / Ivy

Go to download

Closure Compiler is a JavaScript optimizing compiler. It parses your JavaScript, analyzes it, removes dead code and rewrites and minimizes what's left. It also checks syntax, variable references, and types, and warns about common JavaScript pitfalls. It is used in many of Google's JavaScript apps, including Gmail, Google Web Search, Google Maps, and Google Docs.

There is a newer version: v20240317
Show newest version
/*
 * Copyright 2016 The Closure Compiler Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Polyfills for ES6 Math functions.
 */

$jscomp.math = $jscomp.math || {};


/**
 * Counts the leading zeros in the 32-bit binary representation.
 *
 * 

Polyfills the static function Math.clz32(). * * @param {*} x Any number, or value that can be coerced to a number. * @return {number} The number of leading zero bits. */ $jscomp.math.clz32 = function(x) { // This binary search algorithm is taken from v8. x = Number(x) >>> 0; // first ensure we have a 32-bit unsigned integer. if (x === 0) return 32; let result = 0; if ((x & 0xFFFF0000) === 0) { x <<= 16; result += 16; } if ((x & 0xFF000000) === 0) { x <<= 8; result += 8; } if ((x & 0xF0000000) === 0) { x <<= 4; result += 4; } if ((x & 0xC0000000) === 0) { x <<= 2; result += 2; } if ((x & 0x80000000) === 0) result++; return result; }; /** * Performs C-like 32-bit signed integer multiplication. * *

Polyfills the static function Math.imul(). * * @param {*} a Any number, or value that can be coerced to a number. * @param {*} b Any number, or value that can be coerced to a number. * @return {number} The 32-bit integer product of a and b. */ $jscomp.math.imul = function(a, b) { // This algorithm is taken from v8. // Note: If multiplication overflows 32 bits, then we risk losing // precision. We must therefore break the inputs into 16-bit // words and multiply separately. a = Number(a); b = Number(b); const ah = (a >>> 16) & 0xFFFF; // Treat individual words as unsigned const al = a & 0xFFFF; const bh = (b >>> 16) & 0xFFFF; const bl = b & 0xFFFF; const lh = ((ah * bl + al * bh) << 16) >>> 0; // >>> 0 casts to uint return (al * bl + lh) | 0; // | 0 casts back to signed }; /** * Returns the sign of the number, indicating whether it is * positive, negative, or zero. * *

Polyfills the static function Math.sign(). * * @param {*} x Any number, or value that can be coerced to a number. * @return {number} The sign, +1 if x is positive, -1 if x is * negative, or 0 if x is zero. */ $jscomp.math.sign = function(x) { x = Number(x); return x === 0 || isNaN(x) ? x : x > 0 ? 1 : -1; }; /** * Returns the base-10 logarithm. * *

Polyfills the static function Math.log10(). * * @param {*} x Any number, or value that can be coerced to a number. * @return {number} The common log of x. */ $jscomp.math.log10 = function(x) { return Math.log(x) / Math.LN10; }; /** * Returns the base-2 logarithm. * *

Polyfills the static function Math.log2(). * * @param {*} x Any number, or value that can be coerced to a number. * @return {number} The base-2 log of x. */ $jscomp.math.log2 = function(x) { return Math.log(x) / Math.LN2; }; /** * Returns the natural logarithm of 1+x, implemented in a way that is * accurate for numbers close to zero. * *

Polyfills the static function Math.log1p(). * * @param {*} x Any number, or value that can be coerced to a number. * @return {number} The natural log of 1+x. */ $jscomp.math.log1p = function(x) { // This implementation is based on the Taylor expansion // log(1 + x) ~ x - x^2/2 + x^3/3 - x^4/4 + x^5/5 - ... x = Number(x); if (x < 0.25 && x > -0.25) { let y = x; let d = 1; let z = x; let zPrev = 0; let s = 1; while (zPrev != z) { y *= x; s *= -1; z = (zPrev = z) + s * y / (++d); } return z; } return Math.log(1 + x); }; /** * Exponentiates x and then subtracts one. This is implemented in a * way that is accurate for numbers close to zero. * *

Polyfills the static function Math.expm1(). * * @param {*} x Any number, or value that can be coerced to a number. * @return {number} The exponential of x, less 1. */ $jscomp.math.expm1 = function(x) { // This implementation is based on the Taylor expansion // exp(x) ~ 1 + x + x^2/2 + x^3/6 + x^4/24 + ... x = Number(x); if (x < .25 && x > -.25) { let y = x; let d = 1; let z = x; let zPrev = 0; while (zPrev != z) { y *= x / (++d); z = (zPrev = z) + y; } return z; } return Math.exp(x) - 1; }; /** * Computes the hyperbolic cosine. * *

Polyfills the static function Math.cosh(). * * @param {*} x Any number, or value that can be coerced to a number. * @return {number} The hyperbolic cosine of x. */ $jscomp.math.cosh = function(x) { x = Number(x); return (Math.exp(x) + Math.exp(-x)) / 2; }; /** * Computes the hyperbolic sine. * *

Polyfills the static function Math.sinh(). * * @param {*} x Any number, or value that can be coerced to a number. * @return {number} The hyperbolic sine of x. */ $jscomp.math.sinh = function(x) { x = Number(x); if (x === 0) return x; return (Math.exp(x) - Math.exp(-x)) / 2; }; /** * Computes the hyperbolic tangent. * *

Polyfills the static function Math.tanh(). * * @param {*} x Any number, or value that can be coerced to a number. * @return {number} The hyperbolic tangent of x. */ $jscomp.math.tanh = function(x) { x = Number(x); if (x === 0) return x; // Ensure exponent is negative to prevent overflow. const y = Math.exp(2 * -Math.abs(x)); const z = (1 - y) / (1 + y); return x < 0 ? -z : z; }; /** * Computes the inverse hyperbolic cosine. * *

Polyfills the static function Math.acosh(). * * @param {*} x Any number, or value that can be coerced to a number. * @return {number} The inverse hyperbolic cosine of x. */ $jscomp.math.acosh = function(x) { x = Number(x); return Math.log(x + Math.sqrt(x * x - 1)); }; /** * Computes the inverse hyperbolic sine. * *

Polyfills the static function Math.asinh(). * * @param {*} x Any number, or value that can be coerced to a number. * @return {number} The inverse hyperbolic sine of x. */ $jscomp.math.asinh = function(x) { x = Number(x); if (x === 0) return x; const y = Math.log(Math.abs(x) + Math.sqrt(x * x + 1)); return x < 0 ? -y : y; }; /** * Computes the inverse hyperbolic tangent. * *

Polyfills the static function Math.atanh(). * * @param {*} x Any number, or value that can be coerced to a number. * @return {number} The inverse hyperbolic tangent of x. */ $jscomp.math.atanh = function(x) { x = Number(x); return ($jscomp.math.log1p(x) - $jscomp.math.log1p(-x)) / 2; }; /** * Returns the sum of its arguments in quadrature. * *

Polyfills the static function Math.hypot(). * * @param {*} x Any number, or value that can be coerced to a number. * @param {*} y Any number, or value that can be coerced to a number. * @param {...*} rest More numbers. * @return {number} The square root of the sum of the squares. */ $jscomp.math.hypot = function(x, y, ...rest) { // Make the type checker happy. x = Number(x); y = Number(y); // Note: we need to normalize the numbers in case of over/underflow. let max = Math.max(Math.abs(x), Math.abs(y)); for (let z of rest) { max = Math.max(max, Math.abs(z)); } if (max > 1e100 || max < 1e-100) { x = x / max; y = y / max; let sum = x * x + y * y; for (let z of rest) { z = Number(z) / max; sum += z * z; } return Math.sqrt(sum) * max; } else { let sum = x * x + y * y; for (let z of rest) { z = Number(z); sum += z * z; } return Math.sqrt(sum); } }; /** * Truncates any fractional digits from its argument (towards zero). * *

Polyfills the static function Math.trunc(). * * @param {*} x Any number, or value that can be coerced to a number. * @return {number} */ $jscomp.math.trunc = function(x) { x = Number(x); if (isNaN(x) || x === Infinity || x === -Infinity || x === 0) return x; const y = Math.floor(Math.abs(x)); return x < 0 ? -y : y; }; /** * Returns the cube root of the number, handling negatives safely. * *

Polyfills the static function Math.cbrt(). * * @param {*} x Any number, or value that can be coerced into a number. * @return {number} The cube root of x. */ $jscomp.math.cbrt = function(x) { if (x === 0) return x; x = Number(x); const y = Math.pow(Math.abs(x), 1 / 3); return x < 0 ? -y : y; };





© 2015 - 2025 Weber Informatics LLC | Privacy Policy