简体   繁体   English

JavaScript的xor结果与Java不同

[英]JavaScript's xor result different than the one of Java

SOLUTION

I had a bug in my internal conversion logic. 我的内部转换逻辑中有一个错误。

ORIGINAL QUESTION 原始问题

I need to implement an algorithm both in Java and JavaScript, whereas the Java implementation and calculation result is the reference. 我需要在Java和JavaScript中实现算法,而Java实现和计算结果是参考。 However, when invoking the XOR operator on a "negative" value (I know that Java and JavaScript make use of 2's complement) causes Java's result to be positive, whereas the JavaScript result is negative, as shown in the output below: 但是,当在“负”值上调用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        

Below you can see the Java source code: 您可以在下面看到Java源代码:

private 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);
}

The following snippet shows the JavaScript code: 以下代码段显示了JavaScript代码:

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);

The array with the numbers is equal in the Java as well as in the JavaScript version, as show below (all numbers are decimal numbers): 具有数字的数组在Java和JavaScript版本中是相等的,如下所示(所有数字都是十进制数字):

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

I have already tried replacing the byte array with an integer array, but it has not helped. 我已经尝试用整数数组替换字节数组,但它没有帮助。 I'm using WebKit's JavaScriptCore engine. 我正在使用WebKit的JavaScriptCore引擎。

Seeing the values, I suspect that Java is sign extending the 223 when you convert it to a series of bytes and Javascript isn't. 看到这些值,我怀疑当你将它转换为一系列字节而Javascript不是时,Java会扩展223。 223 = 0xDF = 0xFFFFFFDF when sign extended.... 符号扩展时223 = 0xDF = 0xFFFFFFDF ....

Things to be careful about when porting between Java and JavaScript. 在Java和JavaScript之间移植时要注意的事项。

Bitwise shift operators only operate on 32 bit values in Javascript. 按位移位运算符仅在Javascript中以32位值运行。 JavaScript internally represents all numbers as 64 bit floats and does not, distinguish between floats and ints as Java does. JavaScript在内部将所有数字表示为64位浮点数,而不是像Java那样区分浮点数和整数。 Even more, JavaScript does not have int or float sizes eg there is no byte, int or long types. 更重要的是,JavaScript没有int或float大小,例如没有byte,int或long类型。

There is always a risk becoming unstuck because of the above statements and the difference in the way the languages represents numbers. 由于上述陈述以及语言代表数字的方式不同,总有风险变得不稳定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 c xor结果与javascript xor不同 - c xor result is different than javascript xor JavaScript localeCompare() 返回的结果与 Java compareTo() 不同 - JavaScript localeCompare() returns different result than Java compareTo() Javascript Xor ^ 0返回不良结果 - Javascript xor ^ with 0 return bad result javascript function 返回的结果与预期不同 - javascript function return different result than expected 一键调用两个javascript函数所得到的结果与两次单击所得到的结果不同 - Calling two javascript functions with one button click gives a different result than with two 为什么 C# 中的签名算法给出的结果与 Javascript 中的不同 - Why does signing algorithm in C# give different result than the one in Javascript array.push产生的结果与console.log中Java堆算法的结果不同 - array.push produces different result than console.log for Heap's Algorithm in Javascript javascript按位异或产生不一致的结果 - javascript bitwise xor producing inconsistent result javascript中的XOR运算符与python中的XOR运算符不同 - XOR operator in javascript different from XOR operator in python 为什么typeof的结果与传入的表达式的求值结果不同? - Why is typeof's result different than the evaluated result of the expression passed in?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM