diff --git a/.jshintrc b/.jshintrc index 620d8d7..e08e4c7 100644 --- a/.jshintrc +++ b/.jshintrc @@ -1,5 +1,4 @@ { - "bitwise": true, "eqeqeq": true, "forin": true, "freeze": true, diff --git a/src/Math.js b/src/Math.js index 9041361..8e13bdc 100644 --- a/src/Math.js +++ b/src/Math.js @@ -6,30 +6,129 @@ exports.abs = Math.abs; exports.acos = Math.acos; +exports.acosh = Math.acosh || function (x) { + return Math.log(x + Math.sqrt(x * x - 1)); +}; + exports.asin = Math.asin; +exports.asinh = Math.asinh || function (x) { + if (x === -Infinity) { + return x; + } else { + return Math.log(x + Math.sqrt(x * x + 1)); + } +}; + exports.atan = Math.atan; +exports.atanh = Math.atanh || function (x) { + return Math.log((1 + x) / (1 - x)) / 2; +}; + exports.atan2 = function (y) { return function (x) { return Math.atan2(y, x); }; }; +exports.cbrt = Math.cbrt || function (x) { + if (x === 0) { + return x; // +0 or -0 + } else if (x < 0) { + return -Math.pow(-x, 1 / 3); + } else { + return Math.pow(x, 1 / 3); + } +}; + exports.ceil = Math.ceil; +exports.clz32 = Math.clz32 || function (x) { + if (x === 0) { + return 32; + } + return 31 - Math.floor(Math.log(x >>> 0) * Math.LOG2E); +}; + exports.cos = Math.cos; +exports.cosh = Math.cosh || function (x) { + return (Math.exp(x) + Math.exp(-x)) / 2; +}; + exports.exp = Math.exp; +exports.expm1 = Math.expm1 || function (x) { + return Math.exp(x) - 1; +}; + exports.floor = Math.floor; +exports.hypot = Math.hypot ? function (x) { + return function (y) { + return Math.hypot(x, y); + }; +} : function (x) { + return function (y) { + return Math.sqrt(x * x + y * y); + }; +}; + +exports.hypot3 = Math.hypot ? function (x) { + return function (y) { + return function (z) { + return Math.hypot(x, y, z); + }; + }; +} : function (x) { + return function (y) { + return function (z) { + return Math.sqrt(x * x + y * y + z * z); + }; + }; +}; + +function nativeImul(a) { + return function (b) { + return Math.imul(a, b); + }; +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul +function emulatedImul(a) { + /*jshint bitwise: false*/ + return function (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; + }; +} + +exports.imul = Math.imul ? nativeImul : emulatedImul; + exports.trunc = Math.trunc || function (n) { return n < 0 ? Math.ceil(n) : Math.floor(n); }; exports.log = Math.log; +exports.log1p = Math.log1p || function (x) { + return Math.log(x + 1); +}; + +exports.log10 = Math.log10 || function (x) { + return Math.log(x) * Math.LOG10E; +}; + +exports.log2 = Math.log2 || function (x) { + return Math.log(x) * Math.LOG2E; +}; + exports.max = function (n1) { return function (n2) { return Math.max(n1, n2); @@ -56,12 +155,35 @@ exports.remainder = function (n) { exports.round = Math.round; +exports.sign = Math.sign || function (x) { + if (x > 0) { + return 1; + } else if (x < 0) { + return -1; + } else { + return +x; // +0 or -0 or NaN + } +}; + exports.sin = Math.sin; +exports.sinh = Math.sinh || function (x) { + return (Math.exp(x) - Math.exp(-x)) / 2; +}; + exports.sqrt = Math.sqrt; exports.tan = Math.tan; +exports.tanh = Math.tanh || function (x) { + var ex = Math.exp(2 * x); + if (ex === Infinity) { + return 1; + } else { + return (ex - 1) / (ex + 1); + } +}; + exports.e = Math.E; exports.ln2 = Math.LN2; diff --git a/src/Math.purs b/src/Math.purs index a8f2516..efdb5f7 100644 --- a/src/Math.purs +++ b/src/Math.purs @@ -11,12 +11,21 @@ foreign import abs :: Number -> Number -- | Returns the inverse cosine of the argument. foreign import acos :: Number -> Radians +-- | Returns the inverse hyperbolic cosine of the argument. +foreign import acosh :: Number -> Number + -- | Returns the inverse sine of the argument. foreign import asin :: Number -> Radians +-- | Returns the inverse hyperbolic sine of the argument. +foreign import asinh :: Number -> Number + -- | Returns the inverse tangent of the argument. foreign import atan :: Number -> Radians +-- | Returns the inverse hyperbolic tangent of the argument. +foreign import atanh :: Number -> Number + -- | Four-quadrant tangent inverse. Given the arguments `y` and `x`, returns -- | the inverse tangent of `y / x`, where the signs of both arguments are used -- | to determine the sign of the result. @@ -24,21 +33,51 @@ foreign import atan :: Number -> Radians -- | The result is the angle between the positive x axis and a point `(x, y)`. foreign import atan2 :: Number -> Number -> Radians +-- | Returns the cube root of the argument. +foreign import cbrt :: Number -> Number + -- | Returns the smallest integer not smaller than the argument. foreign import ceil :: Number -> Number +-- | Returns the number of leading zeroes of a 32-bit integer. +foreign import clz32 :: Int -> Int + -- | Returns the cosine of the argument. foreign import cos :: Radians -> Number +-- | Returns the hyperbolic cosine of the argument. +foreign import cosh :: Number -> Number + -- | Returns `e` exponentiated to the power of the argument. foreign import exp :: Number -> Number +-- | Returns `exp x - 1` for the argument `x`. +foreign import expm1 :: Number -> Number + -- | Returns the largest integer not larger than the argument. foreign import floor :: Number -> Number +-- | Returns the square root of the sum of squares of the arguments. +foreign import hypot :: Number -> Number -> Number + +-- | Returns the square root of the sum of squares of the arguments. +foreign import hypot3 :: Number -> Number -> Number -> Number + +-- | Returns the result of the C-like 32-bit multiplication of the two arguments. +foreign import imul :: Int -> Int -> Int + -- | Returns the natural logarithm of a number. foreign import log :: Number -> Number +-- | Returns the natural logarithm of `1 + x` for a number `x`. +foreign import log1p :: Number -> Number + +-- | Returns the base 10 logarithm of a number. +foreign import log10 :: Number -> Number + +-- | Returns the base 2 logarithm of a number. +foreign import log2 :: Number -> Number + -- | Returns the largest of two numbers. foreign import max :: Number -> Number -> Number @@ -51,15 +90,24 @@ foreign import pow :: Number -> Number -> Number -- | Returns the integer closest to the argument. foreign import round :: Number -> Number +-- | Returns the sign of the argument. +foreign import sign :: Number -> Number + -- | Returns the sine of the argument. foreign import sin :: Radians -> Number +-- | Returns the hyperbolic sine of the argument. +foreign import sinh :: Number -> Number + -- | Returns the square root of the argument. foreign import sqrt :: Number -> Number -- | Returns the tangent of the argument. foreign import tan :: Radians -> Number +-- | Returns the hyperbolic tangent of the argument. +foreign import tanh :: Number -> Number + -- | Truncates the decimal portion of a number. Equivalent to `floor` if the -- | number is positive, and `ceil` if the number is negative. foreign import trunc :: Number -> Number