【C++編程基礎】-詳解C++中的移位運算

移位運算:

  • 邏輯移位

邏輯移位是指邏輯左移和邏輯右移,移出的空位都用0來補。

  • 算術移位

算術移位 就需要分有符號型值和無符號型值

  1. 對於無符號型值,算術移位等同於邏輯移位。 
  2. 而對於有符號型值 ,算術左移等同於邏輯左移,算術右移補的是符號位,正數補0,負數補1

其中,第2點涉及到負數在計算機中的存儲方式:

首先複習一下原碼、反碼、補碼

有符號型值分爲正數和負數(包括正浮點數,和負浮點數),規定最高位爲符號位,正數爲0,負數爲1。

原碼:10進制轉換成2進制是原碼,只不過正數的原碼是本身符號位爲0,負數的原碼符號位爲1(1的原碼是0000 0001,-1的原碼是1000 0001)。

反碼: 正數的反碼是本身,負數的反碼是負數的原碼非符號位0變爲1,1變爲0(-1的原碼是1000 0001   它的反碼就是 1111 1110)。

補碼: 正數的補碼是本身,負數的補碼就是負數的反碼加1(-1的原碼是1000 0001,它的反碼就是 1111 1110  它的補碼就是 1111 1111)。

總結:正數的原碼,反碼 ,補碼三值合一, 負數的原碼,反碼,補碼不同。事實證明,計算機中負數是以補碼存儲的,也可以推廣到——計算機中所有數都是以補碼形式存儲的

!!!補碼求原碼的過程,依然是(1)符號位不變,其它位取反;(2)符號位不參與計算,其餘加1。

詳見原文:負數在計算機中的存儲問題

因此,負數的算術右移,實際上是對補碼的右移。比如:

char i=-8;//原碼爲1000 1000,反碼爲1111 0111,補碼爲1111 1110;
i>>=3;    //右移3位,即補碼右移3位,變成:
          //補碼爲1111 1111,取反爲10000 0000,加1爲1000 0001,爲-1;

VS系列的編譯器中,對無符號型值進行移位時,默認是邏輯左移和邏輯右移;

而對於有符號型值進行移位時,左移還是邏輯左移,但右移時執行的是算術右移

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