Web/JavaScript/Reference/Global objects/Math/imul
The Math.imul() function returns the result of the C-like 32-bit multiplication of the two parameters.
The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
Syntax
var product = Math.imul(a, b);
Parameters
a- First number.
b- Second number.
Return value
The result of the C-like 32-bit multiplication of the given arguments.
Description
Math.imul() allows for 32-bit integer multiplication with C-like semantics. This feature is useful for projects like Emscripten.
Because imul() is a static method of Math, you always use it as Math.imul(), rather than as a method of a Math object you created (Math is not a constructor).
If you use normal JavaScript floating point numbers in imul, you will experience a degrade in performance. This is because of the costly conversion from a floating point to an integer for multiplication, and then converting the multiplied integer back into a floating point. The reason imul exists is because it is faster in only one (so far) circumstance: AsmJS. AsmJS allows for JIST-optimizers to more easily implement internal integers in JavaScript. Multiplying two numbers stored internally as integers (which is only possible with AsmJS) with imul is the only potential circumstance where Math.imul may prove performant in current browsers.
Examples
Using Math.imul()
Math.imul(2, 4); // 8
Math.imul(-1, 8); // -8
Math.imul(-2, -2); // 4
Math.imul(0xffffffff, 5); // -5
Math.imul(0xfffffffe, 5); // -10
Polyfill
This can be emulated with the following function:
if (!Math.imul) Math.imul = function(a, b) {
var aHi = (a >>> 16) & 0xffff;
var aLo = a & 0xffff;
var bHi = (b >>> 16) & 0xffff;
var bLo = 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 ((aLo * bLo) + (((aHi * bLo + aLo * bHi) << 16) >>> 0) | 0);
};
However, the following function is more performant because it is likely that browsers in which this polyfill would be used do not optimize with an internal integer type in JavaScript, instead using floating points for all numbers.
if (!Math.imul) Math.imul = function(opA, opB) {
opB |= 0; // ensure that opB is an integer. opA will automatically be coerced.
// floating points give us 53 bits of precision to work with plus 1 sign bit
// automatically handled for our convienence:
// 1. 0x003fffff /*opA & 0x000fffff*/ * 0x7fffffff /*opB*/ = 0x1fffff7fc00001
// 0x1fffff7fc00001 < Number.MAX_SAFE_INTEGER /*0x1fffffffffffff*/
var result = (opA & 0x003fffff) * opB;
// 2. We can remove an integer coersion from the statement above because:
// 0x1fffff7fc00001 + 0xffc00000 = 0x1fffffff800001
// 0x1fffffff800001 < Number.MAX_SAFE_INTEGER /*0x1fffffffffffff*/
if (opA & 0xffc00000 /*!== 0*/) result += (opA & 0xffc00000) * opB |0;
return result |0;
};
Specifications
| Specification |
|---|
| ECMAScript (ECMA-262)The definition of 'Math.imul' in that specification. |
Browser compatibility
The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.
Update compatibility data on GitHub
| Desktop | Mobile | Server | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
imul
|
Chrome
Full support 28 |
Edge
Full support 12 |
Firefox
Full support 20 |
IE
No support No |
Opera
Full support 16 |
Safari
Full support 7 |
WebView Android
Full support ≤37 |
Chrome Android
Full support 28 |
Firefox Android
Full support 20 |
Opera Android
Full support 15 |
Safari iOS
Full support 7 |
Samsung Internet Android
Full support 1.5 |
nodejs
Full support 0.12 |
Legend
- Full support
- Full support
- No support
- No support
See also
Math.imul() by Mozilla Contributors is licensed under CC-BY-SA 2.5.