根据规范中的文本如下:
Note that the value types i32 and i64 are not inherently signed or unsigned. The interpretation of these types is determined by individual operators.
既然我们不知道传递的i32类型参数的符号,那么i32.add如何对这两个参数进行加法操作呢?如果我们将此函数导出到 JavaScript,应该如何评估结果?例如,0xffffffff 可以被评估为具有不同符号的不同数字(4294967295 或 -1)。
(module
(func (export "addTwo") (param i32 i32) (result i32)
local.get 0
local.get 1
i32.add))
最佳答案
符号对于加法无关紧要。如果您有一些位X
,那么它们可以被解释为有符号值S_X
或无符号值U_X
。重要的是,两者之间的区别是 0
或 2^32
,因为二进制补码的工作原理不同。
例如,如果 X 全部为 1,则 S_X == -1
和 U_X == 2^32 - 1
。请注意差异是 2^32
。如果 X 全部为 0,则两个值都为 0,差值为 0。
因此,您可以编写 S_X = U_X + D_X
,其中 D_X
是差值,可以是 0 或 2^32
。然后将 X
签名添加到 Y
S_X + S_Y = U_X + D_X + U_Y + D_Y = U_X + U_Y
最后一步是重要的一步:我们可以忽略 D_*
值,因为它们是 2^32
的倍数,并且我们假设我们环绕- 也就是说,高于 32 的位将被忽略。
这并非对于所有操作都是如此。例如,出于这个原因,除法有两种运算:有符号和无符号。但加减乘法等,不关心符号。
关于webassembly - WebAssembly 中如何计算类型 "i32"的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63386666/