[英]JavaScript's xor result different than the one of Java
解
我的內部轉換邏輯中有一個錯誤。
原始問題
我需要在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
您可以在下面看到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);
}
以下代碼段顯示了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);
具有數字的數組在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
我已經嘗試用整數數組替換字節數組,但它沒有幫助。 我正在使用WebKit的JavaScriptCore引擎。
看到這些值,我懷疑當你將它轉換為一系列字節而Javascript不是時,Java會擴展223。 符號擴展時223 = 0xDF = 0xFFFFFFDF ....
在Java和JavaScript之間移植時要注意的事項。
按位移位運算符僅在Javascript中以32位值運行。 JavaScript在內部將所有數字表示為64位浮點數,而不是像Java那樣區分浮點數和整數。 更重要的是,JavaScript沒有int或float大小,例如沒有byte,int或long類型。
由於上述陳述以及語言代表數字的方式不同,總有風險變得不穩定。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.