additional Math function

# David Herman (13 years ago)

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:

Math.imul(a, b)>>>0

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.

# Yehuda Katz (13 years ago)

Seems like a small surface-area with a large impact on compilers.

At first glance, looks good to me.

Curiosity: Does this overlap with Brendan's work on value objects (i.e. will it become moot in the face of them)

-- Yehuda Katz (ph) 718.877.1325

# David Herman (13 years ago)

On Nov 2, 2012, at 12:05 PM, Yehuda Katz <wycats at gmail.com> wrote:

Seems like a small surface-area with a large impact on compilers.

At first glance, looks good to me.

Curiosity: Does this overlap with Brendan's work on value objects (i.e. will it become moot in the face of them)

It could become unnecessary if you're working with value objects. If you had ordinary numbers, you'd have to coerce them to u32 and then multiply:

var a = 0x7fffffff, b = 0x7fefefef; // both doubles
var result = int32(a) * int32(b);   // int32

But value objects are still uncertain and at the very least much farther off into the future -- post-ES6. Engines could implement and ship Math.imul in very short order.

# Brendan Eich (13 years ago)

David Herman wrote:

On Nov 2, 2012, at 12:05 PM, Yehuda Katz<wycats at gmail.com> wrote:

Seems like a small surface-area with a large impact on compilers.

At first glance, looks good to me.

Curiosity: Does this overlap with Brendan's work on value objects (i.e. will it become moot in the face of them)

It could become unnecessary if you're working with value objects. If you had ordinary numbers, you'd have to coerce them to u32 and then multiply:

 var a = 0x7fffffff, b = 0x7fefefef; // both doubles
 var result = int32(a) * int32(b);   // int32

But value objects are still uncertain

I'm focusing on int64 and uint64 but making the framework as general under the hood as possible (e.g., the operators stuff, a multimethod variation that's inline-cacheable, based on an idea from Christian Plesner Hansen).

The need for 64-bit ints is pretty strong in Node.js and I think this means value objects are a priority for ES7.

and at the very least much farther off into the future -- post-ES6. Engines could implement and ship Math.imul in very short order.

Agreed, and this kind of micro-evolution is important to support even while working on value objects for post-ES6. It may be we end up with int32 and uint32, but we don't need to if there's no strong use-case not satisfied by Math.imul.

Note that there's no micro-evolutionary step involving Math.imul64 that satisfies the int64/uint64 use-cases Node faces (buffer and file sizes/offsets). You need 64-bit addition, subtraction, and probably other operators -- and you need the data type, not just operations that could be Math methods.

# Tom Schuster (12 years ago)

Math.imul support was just added to the v8 trunk: code.google.com/p/v8/source/detail?r=14450. Is there any ongoing effort to standardize it?

# Rick Waldron (12 years ago)

On Apr 26, 2013 8:42 AM, "Tom Schuster" <tom at schuster.me> wrote:

Math.imul support was just added to the v8 trunk: code.google.com/p/v8/source/detail?r=14450. Is there any ongoing effort to standardize it?

As with Firefox, which you actually implemented :)

bugzilla.mozilla.org/show_bug.cgi?id=808148

There is no record of consensus (that I can locate) since this thread first began. I don't see why anyone object, but we should get it on record.

Rick

On Fri, Nov 2, 2012 at 9:24 PM, Brendan Eich <brendan at mozilla.org> wrote:

David Herman wrote:

On Nov 2, 2012, at 12:05 PM, Yehuda Katz<wycats at gmail.com> wrote:

Seems like a small surface-area with a large impact on compilers.

At first glance, looks good to me.

Curiosity: Does this overlap with Brendan's work on value objects (i.e.

will it become moot in the face of them)

It could become unnecessary if you're working with value objects. If

you

had ordinary numbers, you'd have to coerce them to u32 and then

multiply:

 var a = 0x7fffffff, b = 0x7fefefef; // both doubles
 var result = int32(a) * int32(b);   // int32

But value objects are still uncertain

I'm focusing on int64 and uint64 but making the framework as general

under

the hood as possible (e.g., the operators stuff, a multimethod variation that's inline-cacheable, based on an idea from Christian Plesner

Hansen).

The need for 64-bit ints is pretty strong in Node.js and I think this

means

value objects are a priority for ES7.

and at the very least much farther off into the future -- post-ES6. Engines could implement and ship Math.imul in very short order.

Agreed, and this kind of micro-evolution is important to support even

while

working on value objects for post-ES6. It may be we end up with int32

and

uint32, but we don't need to if there's no strong use-case not

satisfied by

Math.imul.

Note that there's no micro-evolutionary step involving Math.imul64 that satisfies the int64/uint64 use-cases Node faces (buffer and file sizes/offsets). You need 64-bit addition, subtraction, and probably

other

operators -- and you need the data type, not just operations that could

be

# Oliver Hunt (12 years ago)

I landed support for Math.imul in JSC yesterday as well.

Can't find actual documentation on the expected behavior so just copied what mozilla does.

# Rick Waldron (12 years ago)
# Brendan Eich (12 years ago)

We did talk about Math.imul, Dave presented it briefly IIRC last fall. It's a bite-sized win. Should be able to get it into ES6.