聲明:
本文原創,一部分內容引用其他人博客,有個錯字,進行修復一下,本人特別討厭各種無理由複製粘貼,本篇文章只作爲自己參考使用,如有侵權,請原作聯繫本人。
博客鏈接
邏輯位移與算數位移
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。