位运算
我们看一下如何进行位运算,位运算到底有什么用呢?
" 大部分时候我们不会用到位运算,特别是码农时代,明了直接才更有用。但是位运算就没有用处了么?不是,位运算的作用大多体现在研究类运用。位运算生涩难懂,不过有个很明显的优势就是特别快。因为这是计算机看的语言,也是内部运算的语言."*如果在平时编程当中如果正常的运算能更让人理解的话是没必要使用位运算表示的,强行使用无异于炫技罢了,代码是让人看的。
位取反(~)
位取反即之前负数转二进制所用的方式,即0变1,1变0。
1000110001110011
位与(&)
位与即如果两个位进行比较两位同时为1,结果才为1,否则结果为0。
例如: 125 & 7
125 & 7 二进制: 01111101 & 00000111位与比较: 01111101---------------00000111| | | | | | | |× × × × × √ × √| | | | | | | |00000101结果: 125&7 = 00000111 = 5
位或(|)
位或即如果两个位进行比较两位同时为0,结果才为0,否则结果为1。
例如: 125 | 7
125 | 7 二进制: 01111101 | 00000111位或比较: 01111101---------------00000111| | | | | | | |√ × × × × × × ×| | | | | | | |01111111结果: 125|7 = 01111111 = 7
异或(^)
位异或即如果两个位进行比较相同取0,不同取1。
例如: 125 ^ 7(java中^代表异或)
125 ^ 7 二进制: 01111101 ^ 00000111位异或比较: 01111101---------------00000111| | | | | | | |√ × × × × √ × √| | | | | | | |01111010结果: 125^7 = 01111010 = 122
异或的几条性质:
1、交换律2、结合律 (a^b)^c == a^(b^c)3、对于任何数x,都有 x^x=0,x^0=x4、自反性: a^b^b=a^0=a;
编程算法中的作用:交换两个数(利用性质)
publicvoidSwap(int &a, int &b){ if (a != b){ a ^= b; //a=a^b b ^= a; //b=b^(a^b) = (b^b)^a = a a ^= b; //a=(a^b)^a = (a^a)^b = b } }
右移(>>)
将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。
125>>3
125 >> 3右移: 01111101---------------00111110 |1 >> 100011111 |01 >> 200001111 |101 >> 3^ ^ ^ 正数补0负数补1结果: 125>>3 = 00001111 = 15等价与 125/2的3次方的商
左移(<<)
同样的,左移则是将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)。
125>>3
125 >> 3右移: 01111101 ---------------0|11111010 << 101|11110100 << 2011|11101000 << 3 ^ ^ ^ 补0结果: 125<<3 = 11101000 = -24(八位) 125<<3 = 11101000 = 1000(十六位)相当:125*2的3次方(若左移时舍弃的高位不包含1)
无符号右移(>>>)
无符号右移则始终补0,不考虑正负数。
总结:
符号 | 描述 | 运算规则 |
~ | 反 | 1变0,0变1 |
& | 与 | 两个位都为1时,结果才为1 |
| | 或 | 两个位都为0时,结果才为0 |
^ | 异或 | 两个位相同为0,相异为1 |
>> | 右移 | 各二进位全部左移若干位,高位丢弃,低位补0 |
<< | 左移 | 各二进位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移) |