大端法(big endian) 小端法(small endian)

基本概念

不管是大端法還是小端法存儲,計算機在內存中存放數據的順序都是從低地址到高地址,所不同的是首先取低字節的數據存放在低地址還是取高字節數據存放在低地址。
若首先取高字節的數據存放在低地址,則是大端法;
若首先取低字節的數據存放在低地址,則是小端法;

爲什麼會有大端法與小端法

答案是,計算機電路先處理低位字節,效率比較高,因爲計算都是從低位開始的。所以,計算機的內部處理都是小端字節序。
但是,人類還是習慣讀寫大端字節序。所以,除了計算機的內部處理,其他的場合幾乎都是大端字節序,比如網絡傳輸和文件儲存。

優缺點

大端小端沒有誰優誰劣,各自優勢便是對方劣勢:
小端模式 :強制轉換數據不需要調整字節內容,1、2、4字節的存儲方式一樣。
大端模式 :因爲符號位的判定固定爲第一個字節,容易判斷正負。

轉換

舉例來說,處理器讀入一個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);

程序驗證

1.共用體

知道了大端和小端的定義,我們很容易寫代碼判斷一個機器是大端還是小端:

int main(int argc, char* argv[])
{
       union w         
       {   
              int a;             
              char b; 
       }c;

       c.a = 0x0001;
       if(c.b==1)
              printf("small endian\n");
       else if(c.b==0)
              printf("big endian\n");
       else
              printf("error\n");
       return 0;
}

2.指針轉換

int main(int argc, char *argv[])
{
    unsigned int num = 0xff;
    unsigned char *p = &num;
    if(*p == 0xff)
        printf("small endian\n");
    else if(*p == 0)
        printf("big endian\n");
    else
        printf("error\n");
    return 0;
}

參考

http://www.ruanyifeng.com/blog/2016/11/byte-order.html
http://blog.csdn.net/ce123_zhouwei/article/details/6971544

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章