物聯網學習 算術移位和邏輯移位實現分析

2021-09-30 01:15:07 字數 1620 閱讀 9391

算術移位和邏輯移位實現分析

先來看下面這道題:

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進行補充,但必須確保符號位不改變 但我們好奇的...

算術移位邏輯移位

unsigned int i 8 int main 請問 上面的變數i是採用邏輯移位還是算術移位呢?邏輯移位,簡單理解就是物理上按位進行的左右移動,兩頭用0進行補充,不關心數值的符號問題。算術移位,同樣也是物理上按位進行的左右移動,兩頭用0進行補充,但必須確保符號位不改變。邏輯移位是指邏輯左移和邏輯...