C語言中位移問題

聲明:
本文原創,一部分內容引用其他人博客,有個錯字,進行修復一下,本人特別討厭各種無理由複製粘貼,本篇文章只作爲自己參考使用,如有侵權,請原作聯繫本人。

博客鏈接

邏輯位移與算數位移
http://www.cnblogs.com/hnrainll/archive/2011/07/06/2099068.html

正文

在C語言中,涉及位移的運算符有2個,>>表示右移,<<則表示左移。
而彙編指令中,SHL和SHR表示邏輯左移和邏輯右移,SAR和SAL表示算術左移和算術右移。

其中,邏輯左移和算術左移都是寄存器二進制位整體向左移動,並在右邊補0。

而右移則不同,邏輯右移是整體向左移,並在左邊補0
算術右移則是根據原符號位的值補與其相同的值。

根據C標準,如果在位移運算符左邊的變量是有符號數,如int,char,short等,編譯產生的 彙編指令是算術位移指令,如果該變量是無符號數,如unsigned int,unsigned char等,編譯產生的彙編指令則是邏輯位移指令

本文只解釋右移,因爲左移比較簡單

例子:

    unsigned int a = -1;
    int b = -1;

    a = a >> 2;
    b = b >> 2;

    printf("%x\n", a);
    printf("%x\n", a);
    printf("%x \n", b);
    printf("%x \n", b);

結果:

3fffffff
3fffffff
ffffffff
ffffffff

解釋:
計算機存儲負數補碼,取反加1,不明白同學查詢下,不細講

-1
二進制: 0000000000000000000000000000001
取反後: 11111111111111111111111111111110
+1存儲: 11111111111111111111111111111111

無符號位移爲邏輯位移
右移2位左側補0:00111111111111111111111111111111

有符號位移爲算數位移
右移2位,左側補算數位1:111111111111111111111111111111111

擴展:

    printf("%u\n", a);
    printf("%d\n", a);
    printf("%u \n", b);
    printf("%d \n", b);
    結果:
    1073741823
    1073741823
    4294967295
    -1

有些同學對上面的結果表示不明白
%u , %d爲格式化符
在輸出的時候按照提供的格式進行了格式化
a 的二進制形式 3fffffff
當輸出爲u的時候,作爲無符號正常輸出,
輸出爲%d的時候,作爲有符號輸出,
有符號第一位代表符號位,0代表正數,正數的補碼和原碼是一致的。

b 的二進制形式 ffffffff
當輸出爲u的時候,作爲無符號正常輸出,
輸出爲%d的時候,作爲有符號輸出,
有符號第一位代表符號位,1代表正數,負數的補碼與原碼轉換需要取反加1。

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