WebAssembly 中跨平台的位移数字不一致

问题描述 投票:0回答:1

我有这个 Rust 代码

pub const fn decompose(result: i64) -> (bool, u64, u64) {
    let ptr = (result >> 32) as u64;
    let len = ((result << 32) >> 48) as u64;
    let success = ((result << 63) >> 63) == 0;

    (success, ptr, len)
}

它只是简单的位移,假设结果永远不会为负。

这是我在 ts 中的实现

function decompose(result: bigint): CallResult {
  let ptr = result >> 32n;
  let len = (result << 32n) >> 48n;
  let success = (result << 63n) >> 63n == 0n;

  return {
    ptr: ptr,
    len: len,
    status: success,
  };
}

对于 int

844562369609728
它们都给出不同的结果,打字稿给出错误的结果。这是为什么?

Rust 游乐场:https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=e1b421f867f9cb6e9b6af03d6ca835bc

打字稿游乐场:https://www.mycompiler.io/view/48cssguAXa6

根据https://www.assemblescript.org/types.html

i64 是 js 中的 bigint。所以这应该有效吗?

typescript rust webassembly rust-wasm
1个回答
0
投票

这是为什么呢?因为

BigInt
在移位后不会截断为 64 位,而 i64 会截断。

如果您手动截断(例如通过使用

((1n << 64n) - 1n)
位与),您将获得示例输入相同的结果

let ptr = result >> 32n;
let len = ((result << 32n) & ((1n << 64n) - 1n)) >> 48n;
let success = ((result << 63n) & ((1n << 64n) - 1n)) >> 63n == 0n;

游乐场

话虽这么说,我非常同意@Brian61354270的观点,即移动有符号整数是在玩火,我不知道这是否适用于所有输入。

© www.soinside.com 2019 - 2024. All rights reserved.