C#和Javascript位运算符之间不一致

2j4z5cfb  于 2023-01-04  发布在  Java
关注(0)|答案(1)|浏览(132)

给定以下代码:

uint HASHTABLE = 1917507215;
for (uint i = 5; i != 0; i--)
        {
            HASHTABLE = (HASHTABLE ^ ((HASHTABLE << 10 ^ HASHTABLE) << 9 ^ HASHTABLE) << 5) & 0x7fffffff ^ (((HASHTABLE << 7 ^ HASHTABLE) << 10 ^ HASHTABLE) << 9 ^ HASHTABLE) << 5;
            HASHTABLE = HASHTABLE >> 1 | (HASHTABLE & 1) << 0x1f;
        }

我试着把这段代码转换成JavaScript,但是我注意到在计算中有一个不一致的地方,在C#中,循环结束后HASHTABLE的值是1871861428,而在Javascript中,这个值是-275622220。
我怀疑问题出在C#中,值应该是无符号的,而且Javascript可以做32位的位操作符。
这就是为什么我尝试继续使用Long库(https://www.npmjs.com/package/long
因此,我将HASHTABLE值设置为Long.fromValue(HASHTABLE, true),并继续使用Long执行操作,如下所示:

hashTable = Long.fromValue(hashTable, true);
for (let i = 5; i != 0; i--) {
    hashTable = hashTable.xor(
        hashTable.shiftLeft(10).xor(hashTable).shiftLeft(9).xor(hashTable).shiftLeft(5)
      ).and(0x7fffffff).xor(
        hashTable.shiftLeft(7).xor(hashTable).shiftLeft(10).xor(hashTable).shiftLeft(9).xor(hashTable).shiftLeft(5)
    );
    hashTable = hashTable.shiftRight(1).or(hashTable.and(1).shiftLeft(0x1f));
}
hashTable = hashTable.toInt();

但是,即使使用了Long,我的HASHTABLE值在Javascript中也将是4019345076。
基本上,在Javascript中我会得到0xEF9256B4,而在C#中我会正确地得到0x6F9256B4,区别在于第32位(最重要的位)是在JavaScript中设置的,而在C#中不是。
我在这里遗漏了什么,为什么即使在使用Long库之后,JavaScript和C#之间仍然存在这种不一致?

nukf8bse

nukf8bse1#

参见Unsigned_right_shift >>>

let HASHTABLE = 1917507215;
for (let i = 5; i != 0; i--) {
  HASHTABLE = (HASHTABLE ^ ((HASHTABLE << 10 ^ HASHTABLE) << 9 ^ HASHTABLE) << 5) & 0x7fffffff ^ (((HASHTABLE << 7 ^ HASHTABLE) << 10 ^ HASHTABLE) << 9 ^ HASHTABLE) << 5;
  HASHTABLE = HASHTABLE >>> 1 | (HASHTABLE & 1) << 0x1f;
}
console.log(HASHTABLE);

相关问题