理解字節序

gw8428 8年前發布 | 4K 次閱讀 軟件開發

1.

計算機硬件有兩種儲存數據的方式:大端字節序(big endian)和小端字節序(little endian)。

舉例來說,數值 0x2211 使用兩個字節儲存:高位字節是 0x22 ,低位字節是 0x11 。

  • 大端字節序 :高位字節在前,低位字節在后,這是人類讀寫數值的方法。
  • 小端字節序 :低位字節在前,高位字節在后,即以 0x1122 形式儲存。

同理, 0x1234567 的大端字節序和小端字節序的寫法如下圖。

2.

我一直不理解,為什么要有字節序,每次讀寫都要區分,多麻煩!統一使用大端字節序,不是更方便嗎?

上周,我讀到了一篇 文章 ,解答了所有的疑問。而且,我發現原來的理解是錯的,字節序其實很簡單。

3.

首先,為什么會有小端字節序?

答案是,計算機電路先處理低位字節,效率比較高,因為計算都是從低位開始的。所以,計算機的內部處理都是小端字節序。

但是,人類還是習慣讀寫大端字節序。所以,除了計算機的內部處理,其他的場合幾乎都是大端字節序,比如網絡傳輸和文件儲存。

4.

計算機處理字節序的時候,不知道什么是高位字節,什么是低位字節。它只知道按順序讀取字節,先讀第一個字節,再讀第二個字節。

如果是大端字節序,先讀到的就是高位字節,后讀到的就是低位字節。小端字節序正好相反。

理解這一點,才能理解計算機如何處理字節序。

5.

字節序的處理,就是一句話:

"只有讀取的時候,才必須區分字節序,其他情況都不用考慮。"

處理器讀取外部數據的時候,必須知道數據的字節序,將其轉成正確的值。然后,就正常使用這個值,完全不用再考慮字節序。

即使是向外部設備寫入數據,也不用考慮字節序,正常寫入一個值即可。外部設備會自己處理字節序的問題。

6.

舉例來說,處理器讀入一個16位整數。如果是大端字節序,就按下面的方式轉成值。

x = buf[offset] * 256 + buf[offset+1];

上面代碼中, buf 是整個數據塊在內存中的起始地址, offset 是當前正在讀取的位置。第一個字節乘以256,再加上第二個字節,就是大端字節序的值,這個式子可以用邏輯運算符改寫。

x = buf[offset]<<8 | buf[offset+1];

上面代碼中,第一個字節左移8位(即后面添8個 0 ),然后再與第二個字節進行或運算。

如果是小端字節序,用下面的公式轉成值。

x = buf[offset+1] * 256 + buf[offset];

32位整數的求值公式也是一樣的。

/* 大端字節序 */
i = (data[3]<<0) | (data[2]<<8) | (data[1]<<16) | (data[0]<<24);

/* 小端字節序 */
i = (data[0]<<0) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);

(完)

 

來自:http://www.ruanyifeng.com/blog/2016/11/byte-order.html

 

 本文由用戶 gw8428 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!