算術移位和邏輯移位
unsigned int i = 8;
int main()
上面的變數i是採用邏輯移位還是算術移位呢?
邏輯移位,簡單理解就是物理上按位進行的左右移動,兩頭用0進行補充,不關心數值的符號問題
算術移位,同樣也是物理上按位進行的左右移動,兩頭用0進行補充,但必須確保符號位不改變
但我們好奇的是「i<<3」和「i>>3」到底採用的是算術還是邏輯移位呢?其實單從c語言本身來看可能沒有太多突破,因為c最終會被編譯器編譯成目標平台的彙編**,所以必須要結合編譯器和匯程式設計序來分析以上**,下面主要從反彙編入手分析,對arm平台下有關移位的指令有:
lsl(邏輯左移)
lsr(邏輯右移)
ror(迴圈右移)
asl(算術左移)
asr(算術右移)
rrx(帶擴充套件的迴圈右移)
下面我們來看看上面那段c程式的反彙編結果:
結論:說明無符號數採用的是邏輯左移。
那麼經過測試我們發現以下幾份**反彙編結果和上面的情況是一樣的,都是邏輯左移:
signed int i = 8;
int main()
signed int i = -8;
int main()
結論:說明不管是否有無符號型別,也不管值的正負,均採用的是邏輯左移。
接下來看看右移:
unsigned int i = 8;
int main()
反彙編結果:
結論:說明無符號數採用的是邏輯右移。
再看看有符號數的右移操作:
signed int i = 8;
int main()
反彙編結果:
結論:說明有符號數採用的是算術右移。
經過測試發現以下**反彙編結果和上面的情況也是一樣的:
signed int i = -8;
int main()
結論:說明只要是有符號數,不管值是正還是負,右移時採用的都是算術右移。
疑問:按照移位補0的原則,為何左移都是邏輯移位呢?
答疑:先看看「-8」和「8」在計算機記憶體中的值分別是:
0xfffffff8
0x8由於計算機均按補碼儲存數值,所以不管符號正負,左移對於符號位並不產生影響,而右移則就不同了,無符號數怎麼右移都不影響符號位,但是有符號數邏輯右移時高位補0將改變符號位,所以只能採用算術右移。
總結:只有有符號數右移才採用算術右移,否則其它情況都採用邏輯移位操作(邏輯左移或邏輯右移)。原來只要明白計算機是以補碼方式儲存數值的,就一切都清楚了。
算術移位和邏輯移位
算術移位和邏輯移位 unsigned int i 8 int main 上面的變數i是採用邏輯移位還是算術移位呢?邏輯移位,簡單理解就是物理上按位進行的左右移動,兩頭用0進行補充,不關心數值的符號問題 算術移位,同樣也是物理上按位進行的左右移動,兩頭用0進行補充,但必須確保符號位不改變 但我們好奇的...
算術移位邏輯移位
unsigned int i 8 int main 請問 上面的變數i是採用邏輯移位還是算術移位呢?邏輯移位,簡單理解就是物理上按位進行的左右移動,兩頭用0進行補充,不關心數值的符號問題。算術移位,同樣也是物理上按位進行的左右移動,兩頭用0進行補充,但必須確保符號位不改變。邏輯移位是指邏輯左移和邏輯...
邏輯移位與算術移位
1.邏輯移位 不論是左移還是右移都是直接補0,所有位參與移位。2.算術移位 與邏輯移位的區別在於符號位不參與移位。當為雙符號位時,只有最高符號位才是真符號位,低符號位會參與移位,而如果移位後為01或10,則說明溢位。如補碼1,010 0000左移一位後為1,100 0000。當機器數為正時 無論左移...