因爲數字在內存中是以補碼形式存在的,因此,對於移位運算,也是對補碼進行操作。
正數:首先正數的反碼、補碼都是本身,正數的左移就是高位補0,正數的右移就是低位補0。
例如:對於20:
原碼:0001 0100
反碼:0001 0100
補碼:0001 0100
20<<2:0101 0000(80)
20>>2:0000 0101(5)
負數:對於負數的移位運算,首先保證符號位不變,負數的左移就是低位補0,負數的右移就是高位補1。
負數的左移:首先根據負數的原碼求出負數的補碼(符號位不變,其餘位按照原碼取反加1),然後保證符號位不變,其餘位向左移動到X位,在移動的過程中,低位補0。等移位完成以後,然後保持符號位不變,其餘按位取反加1,得到移位後所對應數的原碼。
負數的右移:首先根據負數的原碼求出負數的補碼(符號位不變,其餘位按照原碼取反加1),然後保證符號位不變,其餘位向右移動到X位,在移動的過程中,高位補1。等移位完成以後,然後保持符號位不變,其餘按位取反加1,得到移位後所對應數的原碼。
例如:對於-20:
原碼:0001 0100
反碼:1110 1011
補碼:1110 1100
-20<<2:補碼左移兩位:1011 0000,取反:1100 1111 ,加1:1101 0000(-80)
-20>>2:補碼右移兩位:1111 1011,取反:1000 0100 ,加1:1000 0101(-5)
驗證如下:
#include<iostream>
#include<string>
#include <limits>
using namespace std;
int main()
{
int A = 20;
int Az = A<<2;
int Ay = A>>2;
cout << Az << endl;
cout << Ay << endl;
int B = -20;
int Bz = B<<2;
int By = B>>2;
cout << Bz << endl;
cout << By << endl;
return 0;
}