這裏有幾個問題。全速USB-Sync是32位。 int
能夠包含數據,但不能作爲無符號整數。您的代碼將其存儲爲long
的唯一原因是將0x80000000
至0xFFFFFFFF
的值存儲爲正數。但是,僅使用long
的最低有效32位。
爲了計算流中的第一小尾數32位無符號數,並將其存儲爲long
,使用:
long ll = (buffer[0] & 0xFF)
| ((buffer[1] & 0xFF) << 8)
| ((buffer[2] & 0xFF) << 16)
| ((buffer[3] & 0xFFL) << 24);
這裏發生的事情的細目:
你在同步數據包十六進制是0x17E1444C
。 USB使用little-endian傳輸此值,這意味着最低有效字節首先被髮送。在電線,字節來順序如下:
4C 44 17 E1
要擊穿步驟:
long ll = buffer[0] & 0xFF;
// ll == 0x4C & 0x000000FF
// == (long) 0x0000004C
// == 0x000000000000004C
ll |= (buffer[1] && 0xFF) << 8;
// ll == 0x000000000000004C | ((0x44 & 0x000000FF) << 8)
// == 0x000000000000004C | (0x00000044 << 8)
// == 0x000000000000004C | 0x00004400
// == 0x000000000000004C | (long) 0x00004400
// == 0x000000000000004C | 0x0000000000004400
// == 0x000000000000004C
ll |= (buffer[2] & 0xFF) << 16;
// ll == 0x000000000000444C | ((0xE1 & 0x000000FF) << 16)
// == 0x000000000000444C | (0x000000E1 << 16)
// == 0x000000000000444C | 0x00E10000
// == 0x000000000000444C | (long) 0x00E10000
// == 0x000000000000444C | 0x0000000000E10000
// == 0x0000000000E1444C
這最後列入說明了爲什麼我們使用& 0xFF
。如果不使用此位與運算,這裏不使用& 0xFF
會發生什麼:
ll |= buffer[2] << 16;
// ll == 0x000000000000444C | ((int) 0xE1) << 16)
// == 0x000000000000444C | (0xFFFFFFE1 << 16)
// == 0x000000000000444C | 0xFFE10000
// == 0x000000000000444C | (long) 0xFFE10000
// == 0x000000000000444C | 0xFFFFFFFFFFE10000
// == 0xFFFFFFFFFFE1444C
這是因爲E1
超過最大正byte
(0x7F
),因此它爲負數處理。直接投射到int
時,負號被保留。爲了避免這種行爲,我們使用完整的8位AND將其轉換爲int
。
現在回到過程。最後一個字節:
ll |= (buffer[3] & 0xFFL) << 24;
// ll == 0x0000000000E1444C | ((0x17 & 0x00000000000000FF) << 24)
// == 0x0000000000E1444C | (0x0000000000000017 << 24)
// == 0x0000000000E1444C | 0x0000000017000000
// == 0x0000000017E1444C
你會發現過去的按位與使用long
版本的0xFF
以上進行。這是因爲如果最低有效字節超過最大正字節(0x7F
),則24位(或更高)的左移有可能產生負的int
。想象一下,而不是17
,最後一個字節是A7
。下面是使用使用& 0xFF
,而不是& 0xFFL
時會發生什麼:
ll |= (buffer[3] & 0xFF) << 24;
// ll == 0x0000000000E1444C | ((0xA7 & 0x000000FF) << 24)
// == 0x0000000000E1444C | (0x000000A7 << 24)
// == 0x0000000000E1444C | 0xA7000000
// == 0x0000000000E1444C | (long) 0xA7000000
// == 0x0000000000E1444C | 0xFFFFFFA7000000
// == 0xFFFFFFFFA7E1444C
'Sync'聽起來更像是一個64位** **價值... –
64個字節是遠遠超過可容納在'long'。請告訴我們這些64字節是什麼。 –
我會嘗試猜...你想讀取64個字節,並且如果第一個字節是0xEECCAAFF,你有* Sync *嗎? –