我正在爲JavaScript類(特別是Typescript)類項目編寫客戶端Python字節碼解釋器。解析字節碼會很好,直到我嘗試了一個負數。將負面的Python元帥int整理成Javascript數字
在Python中,marshal.dumps(2)
給出'i\x02\x00\x00\x00'
和marshal.dumps(-2)
給出'i\xfe\xff\xff\xff'
。這是有道理的,因爲Python用至少32位精度的二進制補碼錶示整數。
在我的Typescript代碼中,我使用等效的Node.js的Buffer類(通過名爲BrowserFS的庫,而不是ArrayBuffers等)來讀取數據。當我看到字符'i'(即buffer.readUInt8(offset) == 105
,表示接下來的事情是一個int)時,我在下一個偏移量上調用readInt32LE
來讀取一個小尾數符號long(4字節)。這適用於正數,但不適用於負數:對於1,我得到'1',但對於'-1',我得到'-272777233'之類的東西。
我想JavaScript表示64位(浮點數)的數字。因此,它好像下面應該工作:
var longval = buffer.readInt32LE(offset); // reads a 4-byte long, gives -272777233
var low32Bits = longval & 0xffff0000; //take the little endian 'most significant' 32 bits
var newval = ~low32Bits + 1; //invert the bits and add 1 to negate the original value
//but now newval = 272826368 instead of -2
我已經嘗試了很多不同的東西,我一直停留在這幾天。我無法弄清楚如何使用Javascript/Typescript從二進制元帥字符串中恢復Python整數的原始值。另外,我認爲我深刻地誤解了比特是如何工作的。任何想法,將在這裏讚賞。
一些更具體的問題可能是:
- 爲什麼會
buffer.readInt32LE
工作正整數,但不是消極的? - 我是否使用正確的方法來獲取「最高位」或「最低位」32位(即
& 0xffff0000
的工作方式我認爲它是怎樣的?) - 獨立但相關:在實際的「長」比'-2'長),我認爲有一個符號位和一個數量級,我認爲這個信息存儲在數字的'最高'2位(即在
number & 0x000000ff
?) - 這是正確的方式想想這個?
BrowserFS代碼的真正縮減版本適用於負值。你可以發佈四次調用'readUInt8'的輸出來驗證你正在讀取期望的序列'FE FF FF FF'嗎? – 2014-10-26 18:50:16
這是問題的很大一部分 - 我沒有得到預期的順序。相反,對於-2,我得到:ef bf bd ef – k8si 2014-10-26 18:55:52
好像你剛剛讀取流中錯誤的部分,或者Python沒有使用你認爲它的數字格式。我不認爲有任何合理的按位操作順序會將'EF BF BD EF'變成'-2'。 – 2014-10-26 18:59:30