位運算
位運算的運算份量只能是整型或字符型數據,位運算把運算對象看做是由二進位組成的位串信息,按位完成指定的運算,獲得位串信息的結果。
位運算符有:
&(按位與)、|(按位或)、^(按位異或)、~ (按位取反)。
其中,按位取反運算符是單目運算符,其他均爲雙目運算符。
位運算符的優先級從高到低,依次爲~、&、^、|,
其中~的結合方向自右至左,且優先級高於算術運算符,其他運算符的結合方向都是自左至右,且優先級低於關係運算符。
(1)按位與運算符(&)
按位與運算將兩個運算份量的對應位按位遵守如下規則進行計算:
0 & 0 = 0, 0 & 1 = 0, 1 & 0 = 0, 1 & 1 = 1。
即同爲 1 的位,結果爲 1,不然結果爲 0。
例如,設3的內部表示爲
00000011
5的內部表示爲
00000101
則3&5的結果爲
00000001
按位與運算有兩種典型用法,一是取一個位串信息的某幾位,如如下代碼截取x的最低7位:x & 0177。二是讓某變量保留某幾位,其他位置0,如如下代碼讓x只保留最低6位:x = x & 077。以上用法都先要設計好一個常數,該常數只有須要的位是1,不須要的位是0。用它與指定的位串信息按位與。
按位與運算將兩個運算份量的對應位按位遵守如下規則進行計算:
0 & 0 = 0, 0 & 1 = 0, 1 & 0 = 0, 1 & 1 = 1。
即同爲 1 的位,結果爲 1,不然結果爲 0。
例如,設3的內部表示爲
00000011
5的內部表示爲
00000101
則3&5的結果爲
00000001
按位與運算有兩種典型用法,一是取一個位串信息的某幾位,如如下代碼截取x的最低7位:x & 0177。二是讓某變量保留某幾位,其他位置0,如如下代碼讓x只保留最低6位:x = x & 077。以上用法都先要設計好一個常數,該常數只有須要的位是1,不須要的位是0。用它與指定的位串信息按位與。
(2)按位或運算符(|)
按位或運算將兩個運算份量的對應位按位遵守如下規則進行計算:
0 | 0 = 0, 0 | 1 = 1, 1 | 0 = 1, 1 | 1 = 1
即只要有1個是1的位,結果爲1,不然爲0。
例如,023 | 035 結果爲037。
按位或運算的典型用法是將一個位串信息的某幾位置成1。如將要得到最右4爲1,其餘位與變量j的其餘位相同,可用邏輯或運算017|j。若要把這結果賦給變量j,可寫成:
j = 017|j
按位或運算將兩個運算份量的對應位按位遵守如下規則進行計算:
0 | 0 = 0, 0 | 1 = 1, 1 | 0 = 1, 1 | 1 = 1
即只要有1個是1的位,結果爲1,不然爲0。
例如,023 | 035 結果爲037。
按位或運算的典型用法是將一個位串信息的某幾位置成1。如將要得到最右4爲1,其餘位與變量j的其餘位相同,可用邏輯或運算017|j。若要把這結果賦給變量j,可寫成:
j = 017|j
(3)按位異或運算符(^)
按位異或運算將兩個運算份量的對應位按位遵守如下規則進行計算:
0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 0 = 1, 1 ^ 1 = 0
即相應位的值相同的,結果爲 0,不相同的結果爲 1。
例如,013^035結果爲026。
異或運算的意思是求兩個運算份量相應位值是否相異,相異的爲1,相同的爲0。按位異或運算的典型用法是求一個位串信息的某幾位信息的反。如欲求整型變量j的最右4位信息的反,用邏輯異或運算017^j,就能求得j最右4位的信息的反,即原來爲1的位,結果是0,原來爲0的位,結果是1。
按位異或運算將兩個運算份量的對應位按位遵守如下規則進行計算:
0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 0 = 1, 1 ^ 1 = 0
即相應位的值相同的,結果爲 0,不相同的結果爲 1。
例如,013^035結果爲026。
異或運算的意思是求兩個運算份量相應位值是否相異,相異的爲1,相同的爲0。按位異或運算的典型用法是求一個位串信息的某幾位信息的反。如欲求整型變量j的最右4位信息的反,用邏輯異或運算017^j,就能求得j最右4位的信息的反,即原來爲1的位,結果是0,原來爲0的位,結果是1。
(4)按位取反運算符(~)
按位取反運算是單目運算,用來求一個位串信息按位的反,即哪些爲0的位,結果是1,而哪些爲1的位,結果是0。例如, ~7的結果爲0xfff8。
取反運算經常使用來生成與系統實現無關的常數。如要將變量x最低6位置成0,其他位不變,可用代碼x = x & ~077實現。以上代碼與整數x用2個字節仍是用4個字節實現無關。
當兩個長度不一樣的數據進行位運算時(例如long型數據與int型數據),將兩個運算份量的右端對齊進行位運算。若是短的數爲正數,高位用0補滿;若是短的數爲負數,高位用1補滿。若是短的爲無符號整數,則高位老是用0補滿。
位運算用來對位串信息進行運算,獲得位串信息結果。如如下代碼能取下整型變量k的位串信息的最右邊爲1的信息位:((k-1)^k) & k。
按位取反運算是單目運算,用來求一個位串信息按位的反,即哪些爲0的位,結果是1,而哪些爲1的位,結果是0。例如, ~7的結果爲0xfff8。
取反運算經常使用來生成與系統實現無關的常數。如要將變量x最低6位置成0,其他位不變,可用代碼x = x & ~077實現。以上代碼與整數x用2個字節仍是用4個字節實現無關。
當兩個長度不一樣的數據進行位運算時(例如long型數據與int型數據),將兩個運算份量的右端對齊進行位運算。若是短的數爲正數,高位用0補滿;若是短的數爲負數,高位用1補滿。若是短的爲無符號整數,則高位老是用0補滿。
位運算用來對位串信息進行運算,獲得位串信息結果。如如下代碼能取下整型變量k的位串信息的最右邊爲1的信息位:((k-1)^k) & k。
移位運算
移位運算用來
將整型或字符型數據做爲二進位信息串做總體移動。有兩個運算符:
<< (左移) 和 >> (右移)
移位運算是雙目運算,有兩個運算份量,左份量爲移位數據對象,右份量的值爲移位位數。移位運算將左運算份量視做由二進位組成的位串信息,對其做向左或向右移位,獲得新的位串信息。
移位運算符的優先級低於算術運算符,高於關係運算符,它們的結合方向是自左至右。
<< (左移) 和 >> (右移)
移位運算是雙目運算,有兩個運算份量,左份量爲移位數據對象,右份量的值爲移位位數。移位運算將左運算份量視做由二進位組成的位串信息,對其做向左或向右移位,獲得新的位串信息。
移位運算符的優先級低於算術運算符,高於關係運算符,它們的結合方向是自左至右。
(1)左移運算符(<<)
左移運算將一個位串信息向左移指定的位,右端空出的位用0補充。例如014<<2,結果爲060,即48。
左移時,空出的右端用0補充,左端移出的位的信息就被丟棄。在二進制數運算中,在信息沒有因移動而丟失的狀況下,每左移1位至關於乘2。如4 << 2,結果爲16。
左移運算將一個位串信息向左移指定的位,右端空出的位用0補充。例如014<<2,結果爲060,即48。
左移時,空出的右端用0補充,左端移出的位的信息就被丟棄。在二進制數運算中,在信息沒有因移動而丟失的狀況下,每左移1位至關於乘2。如4 << 2,結果爲16。
(2)右移運算符(>>)
右移運算將一個位串信息向右移指定的位,右端移出的位的信息被丟棄。例如12>>2,結果爲3。與左移相反,對於小整數,每右移1位,至關於除以2。在右移時,須要注意符號位問題。對無符號數據,右移時,左端空出的位用0補充。對於帶符號的數據,若是移位前符號位爲0(正數),則左端也是用0補充;若是移位前符號位爲1(負數),則左端用0或用1補充,取決於計算機系統。對於負數右移,稱用0 補充的系統爲「邏輯右移」,用1補充的系統爲「算術右移」。如下代碼能說明讀者上機的系統所採用的右移方法:
printf("%d\n\n\n", -2>>4);
若輸出結果爲-1,是採用算術右移;輸出結果爲一個大整數,則爲邏輯右移。
移位運算與位運算結合能實現許多與位串運算有關的複雜計算。設變量的位自右至左順序編號,自0位至15位,有關指定位的表達式是不超過15的正整數。如下各代碼分別有它們右邊註釋所示的意義:
~(~0 << n) /* 實現最低n位爲1,其他位爲0的位串信息 */
(x >> (1+p-n)) & ~(~0 << n) /* 截取變量x自p位開始的右邊n位的信息 */
new |= ((old >> row) & 1) << (15 – k) /* 截取old變量第row位,並將該位信息裝配到變量new的第15-k位 */
s &= ~(1 << j) /* 將變量s的第j位置成0,其他位不變 */
for(j = 0; ((1 << j) & s) == 0; j++) ; /* 設s不等於全0,代碼尋找最右邊爲1的位的序號j */
右移運算將一個位串信息向右移指定的位,右端移出的位的信息被丟棄。例如12>>2,結果爲3。與左移相反,對於小整數,每右移1位,至關於除以2。在右移時,須要注意符號位問題。對無符號數據,右移時,左端空出的位用0補充。對於帶符號的數據,若是移位前符號位爲0(正數),則左端也是用0補充;若是移位前符號位爲1(負數),則左端用0或用1補充,取決於計算機系統。對於負數右移,稱用0 補充的系統爲「邏輯右移」,用1補充的系統爲「算術右移」。如下代碼能說明讀者上機的系統所採用的右移方法:
printf("%d\n\n\n", -2>>4);
若輸出結果爲-1,是採用算術右移;輸出結果爲一個大整數,則爲邏輯右移。
移位運算與位運算結合能實現許多與位串運算有關的複雜計算。設變量的位自右至左順序編號,自0位至15位,有關指定位的表達式是不超過15的正整數。如下各代碼分別有它們右邊註釋所示的意義:
~(~0 << n) /* 實現最低n位爲1,其他位爲0的位串信息 */
(x >> (1+p-n)) & ~(~0 << n) /* 截取變量x自p位開始的右邊n位的信息 */
new |= ((old >> row) & 1) << (15 – k) /* 截取old變量第row位,並將該位信息裝配到變量new的第15-k位 */
s &= ~(1 << j) /* 將變量s的第j位置成0,其他位不變 */
for(j = 0; ((1 << j) & s) == 0; j++) ; /* 設s不等於全0,代碼尋找最右邊爲1的位的序號j */