From a forum post:
there's no need to make numbers small, it only
matters to keep the number of significant digits below 53
function mult32s(n, m) //signed version
{
n |= 0;
m |= 0;
var nlo = n & 0xffff;
var nhi = n - nlo;
return ( (nhi * m | 0) + (nlo * m) ) | 0;
}
function mult32u(n, m) //unsigned version
{
n >>>= 0;
m >>>= 0;
var nlo = n & 0xffff;
var nhi = n - nlo;
return ( (nhi * m >>> 0) + (nlo * m) ) >>> 0;
}
Both |
and >>>
operators cause the result to be converted to 32-bit integer. In the first case it is converted to a signed integer, in the second case it is converted to an unsigned integer.
In the line of multiplication the first |
/ >>>
operator causes the 64-bit intermediate result with 48-bit significand (in the form 0x NNNN NNNN NNNN 0000
) to drop its higher bits, so the intermediate result is in the form 0x NNNN 0000
.
The second |
/ >>>
operator causes the result of second-multiplication-and-addition to be limited to 32 bits.
In case one of the multiplicands is a constant you can simplify the multiplication further:
function mult32s_with_constant(m) //signed version
{
m |= 0
//var n = 0x12345678;
var nlo = 0x00005678;
var nhi = 0x12340000;
return ( (nhi * m | 0) + (nlo * m) ) | 0;
}
Or, if you know that the result is going to be less than 53 bits, then you can do just:
function mult32s(n, m) //signed version
{
n |= 0;
m |= 0;
return ( n * m ) | 0;
}