JavaScript';s的xor结果与Java的xor结果不同

JavaScript';s的xor结果与Java的xor结果不同,javascript,java,bitwise-operators,xor,Javascript,Java,Bitwise Operators,Xor,解决方案 我的内部转换逻辑有一个bug 原始问题 我需要用Java和JavaScript实现一个算法,而Java实现和计算结果是参考。但是,当对“负值”调用XOR运算符(我知道Java和JavaScript使用2的补码)时,会导致Java的结果为正值,而JavaScript的结果为负值,如下面的输出所示: Java output: hash A: 16777619 hash B: 637696617 hash A: 637696613 hash B: 988196

解决方案

我的内部转换逻辑有一个bug

原始问题

我需要用Java和JavaScript实现一个算法,而Java实现和计算结果是参考。但是,当对“负值”调用XOR运算符(我知道Java和JavaScript使用2的补码)时,会导致Java的结果为正值,而JavaScript的结果为负值,如下面的输出所示:

Java output:
    hash A: 16777619
    hash B: 637696617
    hash A: 637696613
    hash B: 988196095
    hash A: 988196062
    hash B: -1759370886
    hash A: 1759370917    <-- here the JavaScript implementation behaves different
    hash B: -1169850945

JavaScript output:

    hash A: 16777619
    hash B: 637696617
    hash A: 637696613
    hash B: 988196095
    hash A: 988196062
    hash B: -1759370886
    hash A: -1759370843   <-- this result should be equal to the Java result
    hash B: -1883572545        

我已经尝试过用整数数组替换字节数组,但没有效果。我正在使用WebKit的JavaScriptCore引擎。

看到这些值,我怀疑当您将223转换为一系列字节时,Java正在扩展它,而Javascript不是。符号扩展时223=0xDF=0xFFFFDF

在Java和JavaScript之间移植时需要注意的事项。

在Javascript中,按位移位运算符仅对32位值进行操作。 JavaScript在内部将所有的数字表示为64位浮点数,而不是像Java那样区分浮点数和整数。更重要的是,JavaScript没有int或float大小,例如没有byte、int或long类型


由于上述语句以及语言表示数字的方式不同,始终存在不一致的风险。

您是否尝试打印InputNumberRay以查看它们是否不同?如果你的
*PRIME*
常量在这两种情况下都是十六进制文字,那么代码就更容易理解;由于现在不太容易看到您真正想要实现的目标…最后一行(在您突出显示的那一行下面)也不同。关于异或:结果是一个32位整数,以2的补码形式,因此不需要进一步调整。此外,我使用语句
hash |=0private static final int FNV_PRIME = 0x1000193;
private static final int FNV_COMPRESS = 0xFFFF;
...

public long getHash(int inputNumber)
{
    int hash = FNVCalculator.FNV_PRIME;
    ByteBuffer intToByteArrayConverter = ByteBuffer.allocate(4);
    intToByteArrayConverter.putInt(inputNumber);
    byte[] inputValues = intToByteArrayConverter.array();

    // inputValues.length is always equal to 4
    for (byte processCounter = (byte) 0; processCounter < inputValues.length; processCounter++)
    {
        hash ^= inputValues[processCounter];
        System.out.println("hash A: " + hash);
        hash *= FNV_PRIME;
        System.out.println("hash B: " + hash);
    }
    return (hash & FNVCalculator.FNV_COMPRESS);
}
var Constants =
{
    FNV_PRIME: parseInt("1000193", 16),
    FNV_COMPRESS: parseInt("FFFF", 16),
    BYTE_ARRAY_LENGTH: 4,
    ...
};
Object.freeze(Constants);

var hash = Constants.FNV_PRIME;

for (var counter = 0; counter < Constants.BYTE_ARRAY_LENGTH; counter++)
{
    hash ^= inputNumberArray[counter];
    console.log("hash A: " + hash);
    // mutltiply the hash with the 32 bit FNV prime number: 2^24 + 2^8 + 0x93
    // source: https://github.com/wiedi/node-fnv/blob/master/fnv.js
    hash += ((hash << 24) + (hash << 8) + (hash << 7) + (hash << 4) + (hash << 1));
    hash |= 0;
    console.log("hash B: " + hash);
}

return (hash & Constants.FNV_COMPRESS);
Java version:
    inputValues[0]: 0
    inputValues[1]: 12
    inputValues[2]: 33
    inputValues[3]: -33
JavaScript version:
    inputNumberArray[0]: 0
    inputNumberArray[1]: 12
    inputNumberArray[2]: 33
    inputNumberArray[3]: -33