以下是我原来学习位运算时的笔记。今天复习翻出来,顺手贴上。若有不妥请在评论中指出,我会尽快完善,谢谢。

我在学习位运算时参考了Matrix67牛的blog中的相关内容,并且向Ghost牛请教。这些都在下文中有所体现。

下面例子中a0表示运算前的值,a表示运算结果,mask表示掩码。它们都是整型。

  1. 按位与: &

    1&1=1,0&1=0,1&0=0,0&0=0

    可见和1进行“按位与”运算则原位不变,和0进行“按位与”运算则原位变为0。利用这个性质,我们可以用“按位与”运算进行:

    • 提取特定位、清零其余位:

      例如:mask中要保留的位上为1,其他位为0,a=a0&mask

    • 判断int的奇偶(效率比%2高得多):

      例如:(a&1)==0则为偶数,反之为奇数。(原理:因为奇数二进制末位总为1,偶数总为0。原数与00…001进行按位与运算,就得到了a二进制末位的值。)

  2. 按位或: |

    1|1=1,0|1=1,1|0=1,0|0=0

    可见和1进行“按位或”运算则原位变为1,和0进行“按位或”运算则原位不变。利用这个性质,我们可以用“按位或”运算进行:

    • 将某些特定位置为1,其余位不变。

      例如:mask中要置1的位为1,其余位为0,a=a0|mask

  3. 按位异或: ^

    1^1=0,0^1=1,1^0=1,0^0=0

    可见和1进行“按位异或”运算则原位取反,和0进行“按位异或”运算则则原位不变。利用这个性质,我们可以用“按位异或”运算进行:

    • 特定位取反 例如:mask中要取反的位为1,其余为0, a=a0^mask

    • 不用中间变量交换两数的值

      例如:要交换a、b的值只需: a=a^b;b=a^b;a=a^b; 即可。

      (原理:上式即 a=(a^b)^(a^b)^b,b=a^b^b 。由于一个数与它本身进行“按位异或”运算得到0,任何一个数与0进行“按位异或”运算得到它本身,故上式即是: a=[b的原值],b=[a的原值] 。这样就达到了交换a、b的目的。)

  4. 取反:~ 对二进制各位按位取反

  5. 左移:<<

    将一个数的各个二进制位左移若干位。(左丢弃,右补零)。我们可以通过左移进行:

    • int快速*2

      当左移时丢弃的高位不包含1时,则数每左移一位,相当该数乘以2

  6. 右移:>>

    将一个数的各个二进制位右移若干位,右丢弃。对于无符号整数及正整数,左补0;对于负数,补0为“逻辑右移”,补1为“算术右移”,具体是哪个则取决于计算机系统。我们可以通过右移进行:

    • int(正数)快速/2 每左移一位,相当该数乘以2。

下面是一些例题(来自Matrix67牛的blog):

去掉最后一位(101101->10110) x>>1
在最后加一个0(101101->1011010 ...