2011-03-22 62 views
2

我正在從Flash + ActionScript3中的網絡中讀取一個已簽名的64位整數(Java long),並將其存儲爲兩個uint(第一個和最後一個32位)。從兩個任務中獲取編號

var l:LongNumber = new LongNumber(); 
l.msb = socket.readUnsignedInt(); 
l.lsb = socket.readUnsignedInt(); 

我怎樣才能將它轉換成實際的數字爲Number

我知道Number可以包含只有53位整數,而不是64,但它已經足夠了(雖然能夠拋出一個Error轉換大數字時會很好)。

回答

1

是的,readDouble()在這裏沒用,它會將你的64位整數解釋爲一個IEEE 754格式的雙精度浮點數(符號位+11指數位+52個小數位),這會讓你一個垃圾結果。

(Number(msb)* Math.pow(2,32))+ Number(lsb)如果您需要支持負數,則不是完整的解決方案。如果您的數字爲零或正數不大於2^63-1(因此符號位未設置),此代碼只會得到正確的結果。如果符號位被設置,你的代碼將有效地將64位解釋爲一個無符號整數,這不是Java發送給你的東西。如果你正在使用你的解決方案,並想知道爲什麼你總是得到積極的結果,這就是爲什麼。

在一行代碼中支持負數和負數可能有一些非常酷的小技巧,但因爲我現在無法解決這個問題,所以我會直接告訴你我看到的解決方案在我心中:

我會用msb & 0x80000000來讀取符號位。如果沒有設置,請使用上面的公式。如果已設置,請將您的數字從2的補碼格式先轉換爲無符號格式:

msb =(msb^0xFFFFFFFF);

lsb =(lsb^0xFFFFFFFF)+ 1;

然後將您的forumla應用到msb和lsb,並且(因爲符號位已設置)將結果數字乘以-1。

if (msb & 0x80000000) 
{ 
    msb ^= 0xFFFFFFFF; 
    lsb ^= 0xFFFFFFFF; 
    result = -(Number(msb)*4294967296 + Number(lsb) + 1); 
} 
else 
{ 
    result = Number(msb)*4294967296 + Number(lsb); 
} 
+0

我實際上並沒有使用負數,儘管數字已經簽名,但很好知道我是否曾經這麼做過。 – 2011-03-24 16:21:51

+0

只是擡起頭,我在我的計算過程中刪除了符號位歸零步驟,這是我思考過程的一部分,但不是實際計算的一部分 - 這是XORing的一部分自動發生的。如果你有一個負的int,你需要做的就是翻轉所有的位並加一個得到2的補碼,當你通過你的forumla時,它給你負數的絕對值,然後你乘以-1到獲得實際價值。 – 2011-03-25 12:59:02

0

readDouble()
UPD:

var ba:ByteArray = new ByteArray(); 
ba.writeUnsignedInt(uint1); 
ba.writeUnsignedInt(uint2); 
ba.position = 0; 
result = ba.readDouble(); 
+0

如果我做'(msb << 32)+ lsb',它就會變成'msb + lsb'。 'readDouble'從浮點格式讀取,而不是整數。 – 2011-03-22 17:40:22

+0

更新了我的回答 – www0z0k 2011-03-22 18:13:00

1

我發現我自己的解決方案(僅適用於正數)

(Number(msb) * Math.pow(2, 32)) + Number(lsb)

或硬編碼2^32

(Number(msb) * 4294967296) + Number(lsb)