additional Math function
dherman at mozilla.com
Fri Nov 2 11:49:15 PDT 2012
I'd like to add a Math.imul function for doing 32-bit integer multiplication. The use case is for compilers like Emscripten and Mandreel. They generate code to emulate machine operations that can be efficiently JIT compiled, but they don't currently have a good solution for doing integer multiplication. For other operations, like addition, they can use the composition of JS's floating-point addition and coercion to int32 via bitwise or:
t = (a+b)|0;
But you can't do the same trick with multiplication, because multiplying large numbers may lose low bits of precision when it overflows to double. So Emscripten has a compiler switch where you can do the fast-but-incorrect (a*b)|0 or you can do a slow-but-correct pure-JS multiply, which has to split the operation into two multiplications with manual carry. As it turns out, multiplication is the only major operation that doesn't have a clear implementation pattern with existing JS operators.
The semantics is straightforward:
Math.imul(a, b) === ToInt32((ToUint32(a) x ToUint32(b)) mod 2^32)
In other words, convert the two arguments to 32-bit integers and "do what C does." The result is signed, simply as a convention -- signed and unsigned integers are isomorphic (ToUint32 and ToInt32 form the bijection between them). We could also consider adding Math.umul:
Math.umul(a, b) === ToUint32((ToUint32(a) x ToUint32(b)) mod 2^32)
but it's not strictly necessary; it's equivalent to:
It might be nice to have Math.umul available out of the box, but for Emscripten and Mandreel, only one of the two is strictly necessary.
At any rate, this function would be easy for JS engines to implement and optimize, and code generators could benefit from it immediately on engines that support it.
I believe we could add this to the ES6 extended Math operations, because it's extremely simple and well-understood; there's no design necessary.
More information about the es-discuss