我正在尝试用 python 编写以下 javascript 函数
exports.hash = u => {
u += 0xe91aaa35;
u ^= u >>> 16;
u += u << 8;
u ^= u >>> 4;
let a = ( u + ( u << 2 ) ) >>> 19;
return a ^ hashAdjust[ ( u >>> 8 ) & 0x1ff ];
};
最初我想出了以下内容
def hash(u):
u += 0xe91aaa35
u ^= u >> 16
u += u << 8
u ^= u >> 4
a = (u + (u << 2)) >> 19
return a ^ hashAdjust[(u >> 8) & 0x1ff]
但是我注意到这两个函数对于大整数输入返回不同的结果。我做了一些调试并意识到它是因为 javascript 和 python 处理整数的方式不同。虽然 python 具有无限精度的整数,但 javascript 使用 32(有符号)位整数,这意味着如果运算结果为整数,它可以处理的最大整数为 2^31 - 1,最小整数为 -(2^31 - 1)超过这些限制,结果将被截断。我会诚实地承认我不完全理解这一点,所以如果有人能为我解释一下这一点,我将不胜感激
我的主要问题是如何为上面使用的每个按位运算符(异或、左移和右移)创建一个函数来避免这种差异。我 已经找到了一个用于 xor 的工具,它完美地工作并且有点被理解(再次,希望得到解释)。
不幸的是,JS 按位运算将数字转换为 32 位整数,你应该使用 BigInt:
function hash(u){
u = BigInt(u);
u += BigInt(0xe91aaa35);
u ^= u >> 16n;
u += u << 8n;
u ^= u >> 4n;
a = (u + (u << 2n)) >> 19n;
return a ^ (u >> 8n) & BigInt(0x1ff);
}
console.log(hash(123123123123))