2013-11-21 62 views
4

Tom Wu的優秀大整數庫JSBN缺少longValue函數,因此我必須編寫這樣的自己。以下是我的代碼,但它不能產生正確的結果。使用Javascript將BigInteger轉換爲Int64

 
var Cast_Int64 = function (v) 
{ 
    var bytes = v.toByteArray(); 
    var value = 
    (
    (new BigInteger(bytes[0]).and(new BigInteger(255))).shiftLeft(new BigInteger(56)) 
) 
    .or(
     (new BigInteger(bytes[1]).and(new BigInteger(255))).shiftLeft(new BigInteger(48)) 
) 
    .or(
     (new BigInteger(bytes[2]).and(new BigInteger(255))).shiftLeft(new BigInteger(40)) 
) 
    .or(
     (new BigInteger(bytes[3]).and(new BigInteger(255))).shiftLeft(new BigInteger(32)) 
) 
    .or(
     (new BigInteger(bytes[4]).and(new BigInteger(255))).shiftLeft(new BigInteger(24)) 
) 
    .or(
     (new BigInteger(bytes[5]).and(new BigInteger(255))).shiftLeft(new BigInteger(16)) 
) 
    .or(
     (new BigInteger(bytes[6]).and(new BigInteger(255))).shiftLeft(new BigInteger(8)) 
) 
    .or(new BigInteger(bytes[7]).and(new BigInteger(255))); 
    return value; 
}; 

我有一個整數字符串數組,我嘗試轉換爲Int64,但它沒有提供正確的答案。

整數字符串數組是:

 
var arr = [ 
"90655", 
"123423", 
"1", 
"9223372032559808512", 
"18446744071562067967", 
"4294967295", 
"18446744071562067968", 
"0", 
"346457745533644", 
"18446744073623153357" 
]; 

的正確答案(在使用(Int64) C#測試基)爲:

 
90655 
123423 
1 
9223372032559808512 
-2147483649 
4294967295 
-2147483648 
0 
346457745533644 
-86398259 

而我的不正確的答案是:

 
99676226616033280 
135705023634997248 
72057594037927936 
9223372032559808512 
72057594029539327 
72057594021150720 
72057594029539328 
0 
88693182856612864 
72057594037590442 

我有jsbin,您可以在其中測試該功能。

編輯:如果我用這個代替Cast_Int64:

 
var Cast_Int64 = function (v) 
{ 
    return v; 
} 

然後一切順利的話,但所有的數字應該是負的(在C#中試基地),將是錯誤的:

 
90655 
123423 
1 
9223372032559808512 
18446744071562067967 
4294967295 
18446744071562067968 
0 
346457745533644 
18446744073623153357 

該工程

代碼(改編自接受的答案):

 
var Cast_Int64 = function (v) 
{ 
    if (v.compareTo(new BigInteger(2).pow(new BigInteger(63))) > 0) 
    v = v.subtract(new BigInteger(2).pow(new BigInteger(64))); 
    return v; 
} 

或更短(和更快一點):

 
var Cast_Int64 = function (v) 
{ 
    if (v.compareTo(new BigInteger("9223372036854775808",10)) > 0) 
    v = v.subtract(new BigInteger("18446744073709551616",10)); 
    return v; 
} 

我把替換代碼jsbin。順便說一句,已經有Cast_UInt64,Cast_Int32和Cast_UInt32函數。

回答

2

整數算術可以被認爲是modular arithmetic(模,其中p是比特數)。所以負值可以表示爲超過2^(p-1)的值,即-x = 2^p - x。例如,考慮x=1-1 = 2^p - 1。你可以在雙方都加1,然後以2^p爲模,你就會在兩邊都得到0

所以爲了得到正確的結果,只是減去2^64(在你的情況p=64),從每一個值大於2^63

18446744073623153357 - 2^64 = -86398259 
18446744071562067968 - 2^64 = -2147483648 

BTW:這個,你可以推斷出符號和無符號整數之間的連接。

+0

我該如何修改Cast_Int64函數? –

+0

算法在第二段粗略描述。你不明白什麼部分?我不能告訴你要寫什麼代碼,因爲我沒有看過你提到的庫。 –

+0

我明白了。我會將替換添加到問題中。謝謝! –