-
右移運算符
鎖定
- 中文名
- 右移運算符
- 含 義
- 移位運算符的一種
- 用 途
- 程序設計
- 運算符號
- >>
右移運算符基本信息
移位運算符的一種:
C語言中移位運算符
位移位運算符
位移位運算符的運算對象、運算規則與結果、結合性如表2-16所示。
移位時,移出的位數全部丟棄,移出的空位補入的數與左移還是右移有關。如果是左移,則規定補入的數全部是0;如果是右移,還與被移位的數據是否帶符號有關。若是不帶符號數,則補入的數全部為0;若是帶符號數,則補入的數全部等於原數的最左端位上的原數(即原符號位)。具體移位規則如下所示。
位移位運算符的優先級如下:
·位移位運算符是同級別的,結合性是自左向右
正整數的補碼是其二進制表示,與原碼相同 。
求負整數的補碼,將其原碼除符號位外的所有位取反(0變1,1變0,符號位為1不變)後加1。)
[1]
例如,設無符號短整型變量a為0111(對應二進制數為0000 0000 0110 1111),
則:a<<3 結果為0888(對應二進制數為0000 0011 0111 1000),a不變(即運算式本身為一個值,但不改變被操作對象值)
a>>4 結果為006 (對應二進制數為0000 0000 0000 0110),a不變
又如,設短整型變量a為-4(對應二進制數為1111 1111 1111 1100),(在計算機中,負數採用補碼的形式儲存)
則:a<<3 結果為-32(對應二進制數為1111 1111 1110 0000),a不變
a>>4 結果為-1(對應二進制數為1111 1111 1111 1111),a不變
C語言裏的左移和右移運算符
先説左移,左移就是把一個數的所有位都向左移動若干位,在C中用<<運算符.例如:
int i = 1;
i = i << 2; //把i裏的值左移2位
也就是説,1的2進制是000...0001(這裏1前面0的個數和int的位數有關,32位機器,gcc裏有31個0),左移2位之後變成000... 0100,也就是10進制的4,所以説左移1位相當於乘以2,那麼左移n位就是乘以2的n次方了(有符號數不完全適用,因為左移有可能導致符號變化,下面解釋原因)
需要注意的一個問題是int類型最左端的符號位和移位移出去的情況.我們知道,int是有符號的整形數,最左端的1位是符號位,即0正1負,那麼移位的時候就會出現溢出,例如:
int i = 0x40000000; //16進制的40000000,為2進制的01000000...0000
i = i << 1;
那麼,i在左移1位之後就會變成0x80000000,也就是2進制的100000...0000,符號位被置1,其他位全是0,變成了int類型所能表示的最小值,32位的int這個值是-2147483648,溢出.如果再接着把i左移1位會出現什麼情況呢?在C語言中採用了丟棄最高位的處理方法,丟棄了1之後,i的值變成了0.
int i = 1, j = 0x80000000; //設int為32位
i = i << 33; // 33 % 32 = 1 左移1位,i變成2
j = j << 33; // 33 % 32 = 1 左移1位,j變成0,最高位被丟棄
總之左移就是: 丟棄最高位,0補最低位
再説右移,明白了左移的道理,那麼右移就比較好理解了.
右移的概念和左移相反,就是往右邊挪動若干位,運算符是>>.
右移對符號位的處理和左移不同,對於有符號整數來説,比如int類型,右移會保持符號位不變,例如:
int i = 0x80000000;
i = i >> 1; //i的值不會變成0x40000000,而會變成0xc0000000
負數10100110 >>5(假設字長為8位),則得到的是 11111101
總之,在C中,左移是邏輯/算術左移(兩者完全相同),右移是算術右移,會保持符號位不變.實際應用中可以根據情況用左/右移做快速的乘/除運算,這樣會比循環效率高很多.
在很多系統程序中常要求在位(bit)一級進行運算或處理。C語言提供了位運算的功能,這使得C語言也能像彙編語言一樣用來編寫系統程序。
右移運算符作用
& 位邏輯與
| 位邏輯或
^ 位邏輯異或
- 位邏輯反
>> 右移
<< 左移
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
我們要注意區分位運算和邏輯運算。
按位與運算通常用來對某些位清0或保留某些位。例如把a 的高八位清 0 ,保留低八位,可作 a&255 運算 ( 255 的二進制數為0000000011111111)。
main(){
int a=9,b=5,c;
c=a&b;
printf("a=%d\nb=%d\nc=%d\n",a,b,c);
}
例如:9|5可寫算式如下: 00001001|00000101
00001101 (十進制為13)可見9|5=13
main(){
int a=9,b=5,c;
c=a|b;
printf("a=%d\nb=%d\nc=%d\n",a,b,c);
}
3. 按位異或運算按位異或運算符“^”是雙目運算符。其功能是參與運算的兩數各對應的二進位相異或,當兩對應的二進位相異時,結果為1。參與運算數仍以補碼出現,例如9^5可寫成算式如下: 00001001^00000101 00001100 (十進制為12)
main(){
int a=9;
a=a^15;
printf("a=%d\n",a);
}
5. 左移運算左移運算符“<<”是雙目運算符。其功能把“<< ”左邊的運算數的各二進位全部左移若干位,由“<<”右邊的數指定移動的位數,高位丟棄,低位補0。例如: a<<4 指把a的各二進位向左移動4位。如a=00000011(十進制3),左移4位後為00110000(十進制48)。
6. 右移運算右移運算符“>>”是雙目運算符。其功能是把“>> ”左邊的運算數的各二進位全部右移若干位,“>>”右邊的數指定移動的位數。例如:設 a=15,a>>2 表示把000001111右移為00000011(十進制3)。應該説明的是,對於有符號數,在右移時,符號位將隨同移動。當為正數時,最高位補0,而為負數時,符號位為1,最高位是補0或是補1 取決於編譯系統的規定。
main(){
unsigned a,b;
printf("input a number: ");
scanf("%d",&a);
b=a>>5;
b=b&15;
printf("a=%d\tb=%d\n",a,b);
}
請再看一例。
main(){
char a='a',b='b';
int p,c,d;
p=a;
p=(p<<8)|b;
d=p&0xff;
c=(p&0xff00)>>8;
printf("a=%d\nb=%d\nc=%d\nd=%d\n",a,b,c,d);
}
當進行按位與或時,最好使用16進制,在程序中這樣表示:0x01 表示0000 0001
所以,字符類型a的最高位強制1可以這樣:a=a|0x80。其他的可以依次類推!
右移運算符巧用
因為位運算比/運算快,所以可對以下代碼進行優化
x=x/2;
優化
x=x>>1;
查看未知2進制數a的第b個數的值為多少
(a>>b)&1