目錄
基本知識
1.按位與&:把參與運算的兩個數對應的二進制位相與,只有對應的二進制均為1時,結果的對應位才為1,否則為0。如:9&5中9可以寫成(00001001),5可以寫成(00000101),那么9&5的運算結果為0000 0001,輸出結果是1。
- 按位或|:把參與運算的兩個數對應的二進制位相或,也就是只要對應的兩個二進制位有一個為1時,其結果就為1。 如:9|5相當於00001001|00000101,運算結果是00001101,輸出結果是13
3.按位異或^:把參與運算的兩個數對應的二進制位相異或,當對應的二進制位上的數據字不相同時,結果對應為1時,否則為0。如:1^1=0,1^0=1,0^0=0,0^1=1 9^5相當於00001001^00000101,運算結果是00001100,輸出結果是12
4.取反~:把運算數的各個二進制位按位求反。如:~9相當於~(0000 1001),運算結果為1111 0110。
5.左億<<:把“<<”左邊的運算數的各二進制位向左移若干位,“<<”右邊的數是指定移動的位數,高位丟棄,低位補0。 如 :a<<4指把a的各二進位向左移動4位,如a=00000011(十進制為3),左移4位后為00110000(十進制48)。
6.友誼>>:把“>>”左邊的運算數的各二進制位全部右移若干位,“>>”右邊的數是指定移動的位數。如:設a=15,a>>2表示把00001111右移為0000 0011(十進制為3)。
位運算的常用方法
乘以\(2\)運算
int mulTwo(int n) { // 計算 n*2
return n << 1;
}
除以\(2\)運算
int divTwo(int n) { // 負奇數的運算不可用
return n >> 1; // 除以 2
}
乘以\(2\)的\(m\)次方
int mulTwoPower(int n, int m) { // 計算 n*(2^m)
return n << m;
}
除以\(2\)的\(m\)次方
int mulTwoPower(int n, int m) { // 計算 n*(2^m)
return n << m;
}
判斷一個數的奇偶性。
bool isOddNumber(int n)
{
return n & 1;
}
取絕對值(某些機器上,效率比$ n > 0 ? n : -n$ 高)
int abs(int n) {
return (n ^ (n >> 31)) - (n >> 31);
/* n>>31 取得 n 的符號,若 n 為正數,n>>31 等於 0,若 n 為負數,n>>31 等於 - 1
若 n 為正數 n^0=0, 數不變,若 n 為負數有 n^-1
需要計算 n 和 - 1 的補碼,然后進行異或運算,
結果 n 變號並且為 n 的絕對值減 1,再減去 - 1 就是絕對值 */
}
取兩個數的最大值(某些機器上,效率比 \(a > b ? a : b\) 高)
int max(int a, int b) {
return b & ((a - b) >> 31) | a & (~(a - b) >> 31);
/* 如果 a>=b,(a-b)>>31 為 0,否則為 - 1 */
}
取兩個數的最小值(某些機器上,效率比$ a > b ? b : a $高)
int min(int a, int b) {
return a & ((a - b) >> 31) | b & (~(a - b) >> 31);
/* 如果 a>=b,(a-b)>>31 為 0,否則為 - 1 */
}
判斷符號是否相同
bool isSameSign(int x, int y) { // 有 0 的情況例外
return (x ^ y) >=
0; // true 表示 x 和 y 有相同的符號,false 表示 x,y 有相反的符號。
}
計算\(2\)的\(n\)次方
int getFactorialofTwo(int n) { // n > 0
return 1 << n; // 2 的 n 次方
}
判斷一個數是不是 2 的冪
bool isFactorialofTwo(int n) {
return n > 0 ? (n & (n - 1)) == 0 : false;
// 當然你也可以使用下面這種更為簡便的寫法:
// return n > 0 && (n & (n - 1)) == 0;
/* 如果是 2 的冪,n 一定是 100... n-1 就是 1111....
所以做與運算結果為 0 */
}
對\(2\)的\(n\)次方取余
int quyu(int m, int n) { // n 為 2 的次方
return m & (n - 1);
/* 如果是 2 的冪,n 一定是 100... n-1 就是 1111....
所以做與運算結果保留 m 在 n 范圍的非 0 的位 */
}
求兩個整數的平均值
int getAverage(int x, int y) {
return (x + y) >> 1;
}
遍歷一個集合的子集
int b = 0;
do {
// process subset b
} while (b = (b - x) & x);
以上內容搬運自OI Wiki,只是為了以后好找