如何使用JavaScript模拟x86无符号32位整数乘法?

4

使用Emscripten编译此代码:

#include <stdio.h>
int main() {
unsigned long d1 = 0x847c9b5d;
unsigned long q =  0x549530e1;
printf("%lu\n", d1*q);
return 0;
}

产生(使用-g)的产物:
  $d1=-2072208547; //@line 3 "minusmul.c"
  $q=1419063521; //@line 4 "minusmul.c"
  var $2=$d1; //@line 5 "minusmul.c"
  var $3=$q; //@line 5 "minusmul.c"
  var $4=((($2)*($3))|0); //@line 5 "minusmul.c"

使用js(我相信是SpiderMonkey?)或node执行此操作,我得到了结果3217488896。使用本机可执行文件(使用GCC编译),我得到了3217489085。如何使用JavaScript模拟x86无符号32位整数乘法?

1
这是一个关于在JavaScript中如何正确地相乘两个32位整数的问题。是否有一种方法可以避免精度丢失并得到正确的结果?我已经尝试了各种方法,但似乎都无法解决这个问题。 - Waleed Khan
我在duplicate question上发布了一个答案。 - Janus Troelsen
2个回答

1
Javascript使用IEEE-754标准(参见)作为其内部数字表示。这是浮点算术,因此您需要编写自己的库函数来模拟大整数的位运算。有几个库可供使用,例如BigIntBigNumber

据我所知,单精度浮点数可以表示0到2^32-1之间的所有数字,因此我不明白我需要BigInts做什么。 - Janus Troelsen
1
这个话题有很多讨论。请参见https://dev59.com/hnVC5IYBdhLWcg3wZwNT - Jim H.

1
Emscripten可能不支持精确的32位乘法,或者这是一个bug。由于他们在主页上提到有64位数学的软件模拟,我认为这是一个bug。我发现你可以使用CHECK_OVERFLOWS来发现溢出。但它似乎不能“修复”它。要使程序完成CHECK_OVERFLOWS,您需要增加生成源代码中标记为“XXX”的计数。

好的,结果原来是一个错误。[修复在这里](https://github.com/kripken/emscripten/commit/c14a675125a6d94d80561e986549280eee5e958d),[问题在这里](https://github.com/kripken/gmp.js/issues/2) - Janus Troelsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接