多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] # 简介 位运算符: `<<, >>, >>>, &, |, ^, ~` **位操作只能用于整形数据,对float和double类型进行位操作会被编译器报错** ![](https://img.kancloud.cn/8e/6c/8e6c941e96b84ccc0c6692ed3172fa60_843x480.png) 结论: 1. 操作的都是数值型的变量 2. `<<`在一定范围内,每左移一位,相当于数值*2,但是也不能太大 3. `>>`在一定范围内,每右移一位,相当于数值/2,但是也不能太大 4. `>>>`右移以后,最高位拿0补 交换2个数字 好处不会溢出 缺点: 适用的数据类型有限制 ~~~ int m = 2; int n = 3; m = m ^ n; //1 n = m ^ n; // 2 m = m ^ n; // 3 System.out.println("m = " + m + " , n = " + n); //m = 3 , n = 2 ~~~ **js中** ~~~ ~~null;      // => 0 ~~undefined; // => 0 ~~0;         // => 0 ~~{};        // => 0 ~~[];        // => 0 ~~(1/0);     // => 0 ~~false;     // => 0 ~~true;      // => 1 ~~1.2543;    // => 1 ~~4.9;       // => 4 ~~(-2.999);  // => -2 ~~~ # 常用技巧 ## 判断奇偶 只要根据最未位是0还是1来决定,为0就是偶数,为1就是奇数。因此可以用`if ((a & 1) == 0)`代替`if (a % 2 == 0)`来判断a是不是偶数。 下面程序将输出0到100之间的所有奇数。 ~~~ for (i = 0; i < 100; ++i) if (i & 1) printf("%d ", i); putchar('\n'); ~~~ ## 交换两数 一般写法 ~~~ void Swap(int &a, int &b) { if (a != b) { int c = a; a = b; b = c; } } ~~~ 可以用位操作来实现交换两数而不用第三方变量: ~~~ void Swap(int &a, int &b) { if (a != b) { a ^= b; b ^= a; a ^= b; } } ~~~ 可以这样理解: ~~~ 第一步  a^=b 即a=(a^b); 第二步  b^=a 即b=b^(a^b),由于^运算满足交换律,b^(a^b)=b^b^a。由于一个数和自己异或的结果为0并且任何数与0异或都会不变的,所以此时b被赋上了a的值。 第三步 a^=b 就是a=a^b,由于前面二步可知a=(a^b),b=a,所以a=a^b即a=(a^b)^a。故a会被赋上b的值。 再来个实例说明下以加深印象。int a = 13, b = 6; a的二进制为 13=8+4+1=1101(二进制) b的二进制为 6=4+2=110(二进制) 第一步 a^=b  a = 1101 ^ 110 = 1011; 第二步 b^=a  b = 110 ^ 1011 = 1101;即b=13 第三步 a^=b  a = 1011 ^ 1101 = 110;即a=6 ~~~ ## 变换符号 变换符号就是正数变成负数,负数变成正数。 如对于-11和11,可以通过下面的变换方法将-11变成11       1111 0101(二进制) –取反-> 0000 1010(二进制) –加1-> 0000 1011(二进制) 同样可以这样的将11变成-11       0000 1011(二进制) –取反-> 0000 0100(二进制) –加1-> 1111 0101(二进制) 因此变换符号只需要取反后加1即可。完整代码如下: ~~~ //by MoreWindows( http://blog.csdn.net/MoreWindows ) #include <stdio.h> int SignReversal(int a) { return ~a + 1; } int main() { printf("对整数变换符号 --- by MoreWindows( http://blog.csdn.net/MoreWindows ) ---\n\n"); int a = 7, b = -12345; printf("%d %d\n", SignReversal(a), SignReversal(b)); return 0; } ~~~ ## 求绝对值 位操作也可以用来求绝对值,对于负数可以通过对其取反后加1来得到正数。对-6可以这样:       1111 1010(二进制) –取反->0000 0101(二进制) -加1-> 0000 0110(二进制) 来得到6。 因此先移位来取符号位,int i = a >> 31;要注意如果a为正数,i等于0,为负数,i等于-1。然后对i进行判断——如果i等于0,直接返回。否之,返回~a+1。完整代码如下: ~~~ //by MoreWindows( http://blog.csdn.net/MoreWindows ) int my_abs(int a) { int i = a >> 31; return i == 0 ? a : (~a + 1); } ~~~ 现在再分析下。对于任何数,与0异或都会保持不变,与-1即0xFFFFFFFF异或就相当于取反。因此,a与i异或后再减i(因为i为0或-1,所以减i即是要么加0要么加1)也可以得到绝对值。所以可以对上面代码优化下: ~~~ //by MoreWindows( http://blog.csdn.net/MoreWindows ) int my_abs(int a) { int i = a >> 31; return ((a ^ i) - i); } ~~~