JavaScript中的无符号32位整数

9
我该如何在Javascript中模拟32位无符号整数而不依赖于任何外部依赖项?使用`x >>> 0`或`x | 0`的技巧不起作用(对于乘法,它们似乎对加法/减法有效),并且双精度在乘法过程中失去精度。
例如,尝试将2654435769 * 340573321(mod 2 ^ 32)相乘。结果应为1。 这个答案有乘法。那加法/减法/除法呢? 这是沃尔夫拉姆阿尔法的链接,展示了上面的方程式。

但是 2654435769 * 340573321 的结果无法在32位中储存... - Šime Vidas
@Šime Vidas:但是使用模2 ^ 32,这就是他希望通过计算实现的,如果我理解正确的话。 - pimvdb
@pimvdb:是的,这就是32位无符号整数的工作方式——所有操作都在模2^32下执行。 - user1367401
我明白了。我很惊讶双精度浮点数会失去精度,我之前不知道。 - Šime Vidas
这可能会有所帮助:https://dev59.com/hnVC5IYBdhLWcg3wZwNT - lord.didger
2个回答

3
一个32位无符号整数可以存储在Javascript的64位浮点数中--执行加法、减法或除法时不会丢失精度。只需用0xffffffff进行掩码处理以保持在32位整数范围内。乘法超出了可存储范围,但您已经有了一个解决方案。

然而,乘法后的精度可能不够高,因为两个32位的整数相乘会得到一个64位的整数,而64位的浮点数只能表示53位有效数字。有更好的方法吗? - robbie fan
请注意,仍然存在一些可怕的陷阱,例如 (1 << 31).toString(16) === '-80000000'(请注意符号)。这是因为左操作数将被转换为32位整数,这意味着浮点数将被截断,并且不在32位范围内的数字将会溢出/下溢。 为了解决这个问题,使用乘法代替移位,例如 (0x8000 * 65536) 而不是 (0x8000 << 16) - jacobq

1
2020年,您可以使用BigInts进行模仿。
const u32mul = (x, y) => Number((BigInt(x) * BigInt(y)) & 0xFFFFFFFFn);

一个足够智能的编译器应该可以解决这个问题,但我没有进行基准测试,因此请谨慎操作。

当然,另一种选择是使用WebAssembly。如果您需要在这个级别上工作,我强烈建议使用它。


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