gpt4 book ai didi

javascript - JavaScript 中的 32 位带符号乘法与 64 位结果

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:24:39 25 4
gpt4 key购买 nike

我正在用 JavaScript 开发一个虚拟机,需要将两个有符号的 32 位数字与一个 64 位有符号的结果相乘,该结果存储为两个 32 位有符号数字(高位 32 位和低位 32 位)。

我设法通过将两个数字拆分为 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 ];
}

但是,我真的不明白如何对带符号的数字做同样的事情。我唯一能想到的是否定任何负数 ab 使两者都为正数,执行无符号乘法,然后在需要时取反结果,但这感觉就像无知的次优解决方案。关于如何做得更好的任何想法?将 ab 拆分为两个带符号的 16 位数字,每个数字似乎合乎逻辑,但我对如何正确执行其余部分感到迷茫。

附注如果您认为我的未签名实现也不理想,也请随时指出。

最佳答案

将一个有符号的 32 位整数拆分为两个 16 位整数的正确方法是一个有符号的 16 位上半部分和一个无符号的 16 位下半部分——你需要对负数进行调整,上半部分减一,下半部分加 2^16(使其为正数)。

比如数字-100000应该变成-2的上半部分和31072的下半部分。重构可以看到-2 * 2^16 + 31072 == -131072 + 31072 == -100000。

在此之后,您可以像往常一样执行叉乘算法;结果的上半部分将是一个带符号的 32 位整数(因为它是乘积的总和,其中一些是带符号的),下半部分将是一个无符号的 32 位整数。解释它涉及反向执行相同的“技巧”。

顺便说一句,如果您在一台机器上进行 native 乘法运算,那么这对应于您将看到的内容的相当自然的解释。

关于javascript - JavaScript 中的 32 位带符号乘法与 64 位结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13597364/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com