有没有办法在Javascript中正确地乘以两个32位整数?
当我从C中尝试使用时,long long我得到了这个:
printf("0x%llx * %d = %llx\n", 0x4d98ee96ULL, 1812433253,
0x4d98ee96ULL * 1812433253);
==> 0x4d98ee96 * 1812433253 = 20becd7b431e672e
Run Code Online (Sandbox Code Playgroud)
但是从Javascript来看结果是不同的:
x = 0x4d98ee97 * 1812433253;
print("0x4d98ee97 * 1812433253 = " + x.toString(16));
==> 0x4d98ee97 * 1812433253 = 20becd7baf25f000
Run Code Online (Sandbox Code Playgroud)
尾随零使我怀疑Javascript具有奇怪限制的整数分辨率,介于32位和64位之间.
有没有办法得到正确的答案?(如果重要的话,我在x86_64 Fedora 15上使用Mozilla js-1.8.5.)
ant*_*eme 10
这似乎做了我想要的没有外部依赖:
function multiply_uint32(a, b) {
var ah = (a >> 16) & 0xffff, al = a & 0xffff;
var bh = (b >> 16) & 0xffff, bl = b & 0xffff;
var high = ((ah * bl) + (al * bh)) & 0xffff;
return ((high << 16)>>>0) + (al * bl);
}
Run Code Online (Sandbox Code Playgroud)
这将执行32位乘法模2 ^ 32,这是计算的正确下半部分.类似的函数可用于计算正确的上半部分并将其存储在单独的整数中(啊*bh似乎正确),但我不需要那样做.
注意零班.如果没有这个,只要设置了高位,该函数就会产生负值.
来自论坛帖子:
没有必要使数字变小,只需将有效数字保持在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;
}
Run Code Online (Sandbox Code Playgroud)
Both |和>>>运算符都会导致结果转换为32位整数.在第一种情况下,它被转换为有符号整数,在第二种情况下,它被转换为无符号整数.
在乘法行中,第一个|/ >>>运算符导致64位中间结果与48位有效数字(在表单中0x NNNN NNNN NNNN 0000)丢弃其较高位,因此中间结果为形式0x NNNN 0000.
第二个|/ >>>运算符使第二乘法和加法的结果限制为32位.
如果其中一个被乘数是常数,则可以进一步简化乘法:
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;
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您知道结果将小于53位,那么您可以这样做:
function mult32s(n, m) //signed version
{
n |= 0;
m |= 0;
return ( n * m ) | 0;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2754 次 |
| 最近记录: |