From 4deba8e4d10cd25ab9e7c0db48c84bea4e86e91a Mon Sep 17 00:00:00 2001 From: Matthew Leon Date: Sun, 19 Nov 2017 10:48:00 -0500 Subject: [PATCH 1/2] Math.imul --- src/Math.js | 22 ++++++++++++++++++++++ src/Math.purs | 3 +++ 2 files changed, 25 insertions(+) diff --git a/src/Math.js b/src/Math.js index 9041361..b8a35e9 100644 --- a/src/Math.js +++ b/src/Math.js @@ -24,6 +24,28 @@ exports.exp = Math.exp; exports.floor = Math.floor; +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); }; diff --git a/src/Math.purs b/src/Math.purs index a8f2516..00b36f3 100644 --- a/src/Math.purs +++ b/src/Math.purs @@ -36,6 +36,9 @@ foreign import exp :: Number -> Number -- | Returns the largest integer not larger than the argument. foreign import floor :: 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 From 57985b79677051f75878c548426b7b0b0f1c893d Mon Sep 17 00:00:00 2001 From: ARATA Mizuki Date: Sat, 3 Mar 2018 14:04:08 +0900 Subject: [PATCH 2/2] Add more ES6 functions, with polyfills for old browsers. The polyfills use naive method for calculation, and subject to loss of precision and undue overflow. If you want precision on old browsers, you should load a better polyfill beforehand. --- .jshintrc | 1 - src/Math.js | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/Math.purs | 45 +++++++++++++++++++++++ 3 files changed, 145 insertions(+), 1 deletion(-) 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 b8a35e9..8e13bdc 100644 --- a/src/Math.js +++ b/src/Math.js @@ -6,24 +6,89 @@ 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); @@ -52,6 +117,18 @@ exports.trunc = Math.trunc || function (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); @@ -78,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 00b36f3..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,24 +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 @@ -54,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