Source: polyfill/Math.js

// Licensed Materials - Property of IBM
//
// IBM Watson Analytics
//
// (C) Copyright IBM Corp. 2015
//
// US Government Users Restricted Rights - Use, duplication or
// disclosure restricted by GSA ADP Schedule Contract with IBM Corp.

( function( Math, ObjectPolyfill )
{
"use strict";

// This module polyfills bitwise operations.
/*jshint bitwise:false*/

/**
 * Polyfills for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math Math}.
 * @class module:barejs/polyfill.Math
 */

/** @lends module:barejs/polyfill.Math */
var stat = {};

/*istanbul ignore else: We test with __ES__ set to 3*/
if ( __ES__ < 6 )
{
    /**
     * The Math.cbrt() function returns the cube root of a number.
     * @param {number} _x The number to get the cube root of.
     * @returns {number} The cube root of the number
     */
    stat.cbrt = function cbrt( _x )
    {
        var y = Math.pow( Math.abs( _x ), 1/3 );
        return _x < 0 ? -y : y;
    };

    /**
     * The Math.expm1() function returns e^x - 1, where x is the argument, and e the base of the natural logarithms.
     * @param {number} _x The number.
     * @returns {number} A number representing e^x - 1, where e is Euler's number and x is the argument.
     */
    stat.expm1 = function expm1( _x )
    {
        return Math.exp( _x ) - 1;
    };

    /**
     * The Math.hypot() function returns the square root of the sum of squares of its arguments.
     * @returns {number} The square root of the sum of squares of its arguments.
     */
    stat.hypot = function hypot( _a, _b/*, ...*/ )
    {
        for ( var i = 0, len = arguments.length, y = 0, v; i < len; ++i )
        {
            v = Math.abs( arguments[i] );
            if ( v === Infinity )
                return v;
            y += v * v;
        }
        return Math.sqrt( y );
    };

    /**
     * The Math.imul() function returns the result of the C-like 32-bit multiplication of the two parameters.
     * @param {number} _a Operand A.
     * @param {number} _b Operand B.
     * @returns {number} The result of the multiplication.
     */
    stat.imul = function imul( _a, _b )
    {
        var ah = ( _a >>> 16 ) & 0xffff;
        var al = _a & 0xffff;
        var bh = ( _b >>> 16 ) & 0xffff;
        var bl = _b & 0xffff;
        // the shift by 0 fixes the sign on the high part
        // the final |0 converts the unsigned value into a signed value
        return ( ( al * bl ) + ( ( ( ah * bl + al * bh ) << 16 ) >>> 0 ) | 0 );
    };

    ( function()
    {
        var table = [
              32, 31,  0,         16,  0, 30,  3,  0, 15,  0,  0,  0, 29, 10,  2,  0,
               0,  0, 12,         14, 21,  0, 19,  0,  0, 28,  0, 25,  0,  9,  1,  0,
              17,  0,  4,  undefined,  0,  0, 11,  0, 13, 22, 20,  0, 26,  0,  0, 18,
               5,  0,  0,         23,  0, 27,  0,  6,  0, 24,  7,  0,  8,  0,  0,  0];

        /**
         * The Math.clz32() function returns the number of leading zero bits in the 32-bit binary representation of a number.
         * "clz32" is short for CountLeadingZeroes32.
         * @param {number} _x
         * @returns {number}
         */
        stat.clz32 = function clz32( _x )
        {
            var v = _x >>> 0; // convert to unsigned integer

            v |= v >>> 1;
            v |= v >>> 2;
            v |= v >>> 4;
            v |= v >>> 8;
            v |= v >>> 16;

            return table[ Math.imul( v, 0x06EB14F9 ) >>> 26 ];
        };
    }() );

    /**
     * The Math.log1p() function returns the natural logarithm (base e) of 1 + a number.
     * @param {number} _x The value to get the logarithm of.
     * @returns {number} The logarithm of 1 + _x.
     */
    stat.log1p = function log1p( _x )
    {
        return Math.log( 1 + _x );
    };

    /**
     * The Math.log2() function returns the base 2 logarithm of a number.
     * @param {number} _x The value to get the base 2 logarithm of.
     * @returns {number} The base 2 logarithm of _x.
     */
    stat.log2 = function log2( _x )
    {
        return Math.log( _x ) / Math.LN2;
    };

    /**
     * The Math.log10() function returns the base 10 logarithm of a number.
     * Note that this polyfill is subject to rounding errors.
     * @param {number} _x The value to get the base 10 logarithm of.
     * @returns {number} The base 10 logarithm of _x.
     */
    stat.log10 = function log10( _x )
    {
        return Math.log( _x ) / Math.LN10;
    };

    /**
     * The Math.cosh() function returns the hyperbolic cosine of a number.
     * @param {number} _x The value to calculate the cosine of.
     * @returns {number} The hyperbolic cosine.
     */
    stat.cosh = function cosh( _x )
    {
        var y = Math.exp( _x );
        return ( y + 1 / y ) / 2;
    };

    /**
     * The Math.acosh() function returns the hyperbolic arc-cosine of a number.
     * @param {number} _x The value to calculate the arc-cosine of.
     * @returns {number} The hyperbolic arc-cosine.
     */
    stat.acosh = function acosh( _x )
    {
        return Math.log( _x + Math.sqrt( _x * _x - 1 ) );
    };

    /**
     * The Math.sinh() function returns the hyperbolic sine of a number.
     * @param {number} _x The value to calculate the sine of.
     * @returns {number} The hyperbolic sine.
     */
    stat.sinh = function sinh( _x )
    {
        var y = Math.exp( _x );
        return ( y - 1 / y ) / 2;
    };

    /**
     * The Math.asinh() function returns the hyperbolic arcsine of a number.
     * @param {number} _x The value to calculate the arcsine of.
     * @returns {number} The hyperbolic arcsine.
     */
    stat.asinh = function asinh( _x )
    {
        if ( _x === -Infinity )
            return _x;
        else
            return Math.log( _x + Math.sqrt( _x * _x + 1 ) );
    };

    /**
     * The Math.tanh() function returns the hyperbolic tangent of a number.
     * @param {number} _x The value to calculate the tangent of.
     * @returns {number} The hyperbolic tangent.
     */
    stat.tanh = function tanh( _x )
    {
        var y;

        if ( _x === Infinity )
            return 1;
        else if ( _x === -Infinity )
            return -1;
        else
            return ( ( y = Math.exp( 2 * _x ) ) - 1) / ( y + 1 );
    };

    /**
     * The Math.atanh() function returns the hyperbolic arctangent of a number.
     * @param {number} _x The value to calculate the arctangent of.
     * @returns {number} The hyperbolic arctangent.
     */
    stat.atanh = function atanh( _x )
    {
        return Math.log( ( 1 + _x ) / ( 1 - _x ) ) / 2;
    };

    /**
     * The Math.sign() function returns the sign of a number, indicating whether the number is positive, negative or zero.
     * @param {number} _x The number to check
     * @returns {number} This function has 5 kinds of return values, 1, -1, 0, -0, NaN, which represent
     *                  "positive number", "negative number", "positive zero", "negative zero" and NaN respectively.
     */
    stat.sign = function sign( _x )
    {
        _x = +_x; // convert to a number
        if ( _x === 0 || isNaN( _x ) )
            return _x;
        return _x > 0 ? 1 : -1;
    };

    /**
     * Unlike other three Math methods: Math.floor(), Math.ceil() and Math.round(), the way
     * Math.trunc() works is very simple and straightforward, just truncate the dot and the digits
     * behind it, no matter whether the argument is a positive number or a negative number.
     * @param {number} _x The number to truncate.
     * @returns {number} The truncated number
     */
    stat.trunc = function trunc( _x )
    {
        return _x < 0 ? Math.ceil( _x ) : Math.floor( _x );
    };
// End of ES6 polyfill scope
}

ObjectPolyfill.polyfill( Math, stat, null, exports, "Math" );

// End of module
}( Math, require( "./Object" ) ) );