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