我正在用 JavaScript 开发一个 VM,需要将两个带符号的 32 位数字与存储为两个 32 位带符号数字(高 32 位和低 32 位)的 64 位带符号结果相乘。
我设法通过将两个数字拆分为 16 位对并将它们相乘来对无符号数字做同样的事情a*b = (ah * 2^16 + al) * (bh * 2^16 + bl)
:
function mul_32_unsigned( a, b )
{
var ah = a >>> 16;
var bh = b >>> 16;
var al = a & 0xFFFF;
var bl = b & 0xFFFF;
var mid = ah * bl + al * bh;
var albl = al * bl;
var imm = mid + ( albl >>> 16 );
var carry = ( imm > 0xffffffff ) ? 0x10000 : 0;
var lo = ( ( mid << 16 ) + albl ) >>> 0;
var hi = ( ah * bh + ( imm >>> 16 ) + carry ) >>> 0;
return [ lo, hi ];
}
但是,我真的不明白如何对签名号码做同样的事情。我唯一能想到的就是否定任何负数a
或b
使两者都为正数,执行无符号乘法,然后在需要时否定结果,但这感觉像是一个毫无头绪的次优解决方案。关于如何做得更好的任何想法?将a
和b
分成两个有符号的 16 位数字似乎是合乎逻辑的,但是我对如何在没有任何错误的情况下执行其余部分感到迷茫。
ps 如果您认为我的未签名实现也不是最理想的,也请随时指出这一点。