首页 > 解决方案 > 节点异或两个大小不等的数组 - 未定义异或的行为

问题描述

考虑 NodeJS 中的以下示例:

let ar1 = new Uint8Array([1,2,3,4])
let ar2 = new Uint8Array([1,2,3,4,5,6,7,8])
for (var i = 0; i < 8; i++) {
    console.log(ar1[i] ^ ar2[i]);
}

我使用的是 Node 版本 12.22.1,上面的代码输出以下内容:

0
0
0
0
5
6
7
8

在这里,我们看到对一个数组边界之外的元素进行异或运算只会导致另一个数组中元素的值。

仔细观察,我们看到ar1[5] === undefinedtrue。此外,undefined ^ 5 === 5也是如此(技术上是非零值)。因此,假设undefined与 Node 中的任何内容进行异或运算会产生原始值是否安全?

在上下文中,我正在尝试对两个不同大小的 Uint8Arrays 进行异或。最简单的实现是找到数组的最大长度并对每个元素进行异或,将结果存储到列表中。这行得通,但我怀疑依靠任何东西undefined来产生可靠的行为。我可以添加额外的代码以确保不会发生越界访问,但我想知道这在 Node.js 中是否有必要。我还想知道相同的代码是否会在其他 JavaScript 运行时环境中可靠地运行,特别是在 Web 浏览器中。

这是我在此示例中编写的简单 XOR 数组代码。

private static xorArrays(array1: Uint8Array, array2: Uint8Array): Uint8Array 
{
    let length = array1.length > array2.length ? array1.length : array2.length;
    let result = new Uint8Array(length);
    for (let i = 0; i < length; i++) {
        result[i] = array1[i] ^ array2[i];
    }
    return result;
}

标签: node.js

解决方案


因此,假设未定义的 XOR 与 Node 中的任何内容将产生原始值是否安全?

undefined ^ x给出的原因x是因为当您尝试转换undefined为数字(例如+undefined)时,您会得到NaN.

在按位运算符中,NaN0转换为 32 位整数后进行操作(按位运算符根据this进行操作)。这可以通过 、 、 等看到~NaNNaN >> 0规范5 << NaN实际上指定了在 VM 级别上,ToNumeric(undefined)给出(间接)NaN。我找不到任何说明为什么NaN在按位运算符中表示 0 的规范,因此这可能与 VM 相关。

对于您的用例,您可以简单地使用array[i] || 0, 其中undefined(和0)将是虚假的,因此“默认”0改为。然后你知道它总是如何表现,而不是依赖于奇怪的按位运算符的行为undefined


推荐阅读