原碼、反碼、補碼及位操作符,C語言位操作
阿新 • • 發佈:2018-12-19
- 計算機中的所有資料均是以二進位制形式儲存和處理的。所謂位操作就是直接把計算機中的二進位制數進行操作,無須進行資料形式的轉換,故處理速度較快。
1、原碼、反碼和補碼
- 位(bit)
- 是計算機中處理資料的最小單位,其取值只能是 0 或 1。
- 位元組(Byte)
- 是計算機處理資料的基本單位,通常系統中一個位元組為 8 位。即:1 Byte=8 bit。
- 為便於演示,本節表示的原碼、反碼及補碼均預設為 8 位。
- 準確地說,資料在計算機中是以其補碼形式儲存和運算的。在介紹補碼之前,先了解原碼和反碼的概念。
- 正數的原碼、反碼、補碼均相同。
- 原碼:
- 用最高位表示符號位,其餘位表示數值位的編碼稱為原碼。其中,正數的符號位為 0,負數的符號位為 1。
- 負數的反碼:
- 把原碼的符號位保持不變,數值位逐位取反,即可得原碼的反碼。
- 負數的補碼:
- 在反碼的基礎上加 1 即得該原碼的補碼。
- 例如:
- +11 的原碼為: 0000 1011
- +11 的反碼為: 0000 1011
- +11 的補碼為: 0000 1011
- -7 的原碼為:1000 0111
- -7 的反碼為:1111 1000
- -7 的補碼為:1111 1001
- 注意,對補碼再求一次補碼操作就可得該補碼對應的原碼。
2、位操作符
- 語言中提供了 6 個基本的位操作符,如表 2 所示。
- 注意,計算機中位運算操作,均是以二進位制補碼形式進行的。
2.1 按位與(&)
- 只有兩位同時為 1 時,結果才為 1;只要兩位中有一位為 0,則結果為 0。用式子表示為:
0 & 0 = 0 0 & 1 = 0 1 & 0 = 0 1 & 1 = 1
- 複合賦值運算子:&= 表示按位與後賦值。
- 例如,計算 20 和 9 按位與的結果,如下所示。
- 即:20&9=0。
- 應用一:使用 0x01 與一個數按位與,可獲取該數對應二進位制數的最低位。
- 應用二:使用 0x00 與一個數按位與,可使該數低位的一個位元組清零。
- 例如,9&0x1 可求得 9 對應二進位制數 0000 1001 的最低位 1。
- 【例 1】分析以下程式的功能,並輸出其執行結果。
#include<stdio.h> int main (void) { int n; for(n=1;n<=20;n++) if (0==(n&0x1)) printf("%d ",n); printf ("\n"); return 0; }
- 程式執行結果為:
2 4 6 8 10 12 14 16 18 20
- 程式分析:
- n&0x1 的功能是取出 n 對應補碼二進位制數的最低位(最右端位),如果該位為 0,則輸出。二進位制數 bn-1bn-2bn-3…b2b1b0。對應的十進位制數 N 的表示式為:
- N=b0 X 20 + b1 X 21 + b2 X 22 + b3 X 23 + b4 X 24 + …
- 由於從上式中第二項開始的每一項都是偶數,故N是否偶數取決於 b0 是否偶數,故 b0 為 1 時是奇數,為 0 時是偶數。
2.2 按位或(丨)
- 只要兩位中有一位為 1,結果為 1;只有兩位同時為 0 時,結果才為 0。用式子表示為:
0 | 0 = 0 0 | 1 = 1 1 | 0 = 1 1 | 1 = 1
- 複合賦值運算子:|= 按位或後賦值。
- 例如,計算 20 和 9 按位或的結果,如下所示。
- 即: 20 | 9 = 29。
2.3 按位異或(^)
- 當兩位相同時,即同為 1 或同為 0 時,結果為 0;當兩位相異時,即其中一位為 1,另一位為 0 時,結果為 1。即相同為 0,相異為 1。用式子表示為:
0 ^ 0 = 0 0 ^ 1 = 1 1 ^ 0 = 1 1 ^ 1 = 0
- 由此可得按位異或的 6 個性質或特點如下。
- a^0=a。即0與任意數按位異或都得該數本身。
- 1 與任意二進位制位按位異或都得該位取反(0 變 1,1 變 0)。
- a^a=0。即任意數與自身按位異或都得0。
- a^b=b^a。即滿足交換律。
- (a^b)^c=a^(b^c)。即滿足結合律。
- a^b^b=a^(b^b)=a^0=a。
- 複合賦值運算子:^= 按位異或後賦值。
- 例如,計算 22 和 7 按位異或的結果,如下所示。
- 即:22^7=17。
- 【例 2】分析以下程式的功能。
#include<stdio.h> int main (void) { int a=3,b=5; a=a^b; b=a^b; a=a^b; printf("a=%d,b=%d\n",a,b); return 0; }
- 執行結果:
a=5,b=3
- 程式分析:
- 本題是對按位異或的性質和特點的綜合運用,由於沒有使用中間變數,故在理解上存在一定的難度。
- 由於 a=a^b; 故:
- b=a^b=a^b^b=a^(b^b)=a^0=a,即:b=3。
- a=a^b=(a^b)^a=(b^a)^a=b^(a^a)=b^0=b,即:a=5。
- 故實現了 a 與 b 的交換。
2.4 左移(<<)
- 將運算數的各二進位制位均左移若干位,高位丟棄(不包含 1),低位補 0。左移時捨棄的高位不包含 1,則每左移一位,相當於該數乘以 2。
- 複合賦值運算子: <<= 左移後賦值。
- 例如,計算 10 左移兩位的結果,如下所示。
- 丟棄左邊高位移出去的 0,低位補 0。
- 左移一位相當於該數乘以 2,本例中左移兩位,故相當於乘以 4。即:10<<2 = 10 X 2 X 2 = 40。
2.5 右移(>>)
- 將運算數的各二進位制位全部右移若干位,正數左補 0,負數左補 1,右邊移出的位丟棄。
- 複合賦值運算子: >>= 右移後賦值。
- 例如,計算 70 右移兩位的結果,如下所示。
- 丟棄右邊移出去的所有位,由於該數為正數,左邊補 0。
- 右移一位相當於該數除以 2 取整,本例中右移兩位,故相當於除以 4 取整。即:70>>2=70/4 = 17。
2.6 按位取反(~)
- 0 變 1,1 變 0。用式子表示為:
~0 = 1 ~1 = 0
- 應用:~a+1=-a 即對任意數按位取反後加 1,得該數的相反數。
- 例如,計算 10 按位取反的結果,如下所示:
- 由於計算機中位運算均是以補碼形式操作的,正數的補碼是其本身,負數的補碼為其反碼加 1。
- 所得顯然是負數的補碼,對補碼 1111 0101 再做一次求補操作,即可得該補碼對應的原碼。 求 1111 0101 補碼的過程如下所示。
- 反碼 1000 1010 --符號位 1 保持不變,數值位按位取反
- 補碼 1000 1011 --反碼加1
- 根據 (補碼)補碼=原碼
- 故補碼1111 0101對應的原碼為1000 1011=-11,即:~(10)D =~(0100 0110)B補= (1111 0101)B補=-11
- 由此可見,~10+1=-11+1=-10,即滿足 ~a+1=-a。