位运算 | (一)位运算基础入门

前言

位运算是基于整数的二进制表示进行的运算,即运算时是考虑整数对应的二进制表示,并对二进制每一位所考虑的运算。常用的运算符共 6 种,分别为与(&)、或(|)、异或(^)、取反(~)、左移(<<)、右移(>>)和无符号右移(>>>,只有部分语言才有的特性,比如Java)。其中除了&以外,其它几个运算符均为二元运算符。

基础介绍

运算符 运算规则
& 只有两个操作数对应位均为1时才为1,否则为0
| 只有两个操作数对应位均为0时才为0,否则为1
^ 只有两个操作数对应位不相等时才为1,否则为0
~ 将操作数的二进制表示的每一位取反,即0变1,1变0
<< 将操作数的完整二进制表示,去掉高位,低位补0
>> 将操作数的完整二进制表示,去掉低位,若操作数为正数,则高位补0,为负,则补1
>>> 将操作数的完整二进制表示,去掉低位,不管操作数为正还是为负,均补0

特别注意

当进行位移运算时,右操作数位移不应该超过整数的最大位数,当然超过了也不会报错,但不同语言的处理细节有所不同,大家如果感兴趣可以看下《深入理解计算机系统》,里面有具体的介绍。

基础使用

为了运算方便,这里假设每个数都只有4位,半个字节,故只能表示-8 ~ 7,下面先展示每个运算符的使用:

  1. &的使用

    对于2 & 3而言,我们先得到两个数的二进制完整表示:2(0010), 3(0011),然后按照&的规则进行运算:

    0 0 1 0

    &

    0 0 1 1

    0 0 1 0 (2)

  2. |的使用

    对于4 | 1而言,我们同样先得到两个数的二进制完整表示:4(0100),1(0001),然后按照|的规则进行运算:

    0 1 0 0

    |

    0 0 0 1

    0 1 0 1 (5)

  3. ^的使用

    对于6 ^ 2而言,我们还是先得到两个数的二进制完整表示:6(0110),2(0010),然后按照^的规则进行运算:

    0 1 1 0

    ^

    0 0 1 0

    0 1 0 0 (4)

  4. ~的使用

    对于~3而言,我们依旧还是先得到3的二进制完整表示:3(0011),然后按照~的规则进行运算:

    ~

    0 0 1 1

    1 1 0 0 (-4,因为我们上文说了假设数字都是只有四位,因此最高位为符号位)

    正数对应的二进制表示,我们一般经过稍加计算很快就可以得到,对于负数的二进制,则可以通过负数相反数进行取反加1得到。例如为了得到-7的二进制,我们首先知道7的二进制为0111,然后先进行取反操作,得到1000,然后再加1,得到1001,即为-7所对应的二进制表示。

  5. <<的使用

    对于1 << 2而言,我们依然还是先得1的二进制完整表示:1(0001),然后按照<<的规则进行运算:

    舍去最高的2位得到01,然后低位补2个0,得到01000100(4)即为最终的结果,这里需要注意一点,<<操作并不是完全等同于将左操作数 * 2右操作数,在计算机里,由于位数的限制,可能会出现运算溢出,因此,对于1 << 3,按照上述规则得到1000,由于最高位为符号位,因此得到的结果不是8,而是-8,甚至对于1 << 4, 按照上述规则会得到0000,即在这里1 << 4的结果为0,而非16(正常不应该让位移数操作整数的最大位数,这里仅作讲解使用),大家想要验证的话,可以测试0x4000 0000 << 10x 4000 0000 << 2(注意这里是16进制的表示形式,转换为二进制表示的话,需要将每一位转换为对应的4位二进制数)即可。

  6. >>的使用

    由于>>为有符号右移,所以这里展示两个例子先说6 >> 2,我们先得到6的二进制数表示:6(0110),然后按照>>的规则进行运算:首先舍去低2位,得到01,由于为正(最高符号为为0),因此高位需要补2个0,得到0001(1),即为最终的结果。然后再说一个负数的例子,对于-7 >> 1,我们先得到-7的二进制完整表示:-7(1001),然后先舍去低1位,得到100,由于为负(最高符号为为1),因此高位需要补1个1,得到1100(-4),即为最终的结果。

  7. >>>的使用

    >>>>>的唯一区别就是当左操作数为负数的时候,当运算先舍去低位后,高位也同样补0了,而不是7,还是举刚才-7 >>> 1的例子,我们先得到-7的二进制完整表示:-7(1001),然后先舍去低1位,得到100,最后我们在高位补0,得到0100,即为最终的结果。如果想自己进行代码验证的话,-7的32进制表示为0xffff fff5,舍弃低位,高位补0,会得到0x7fff fffc(2147483644)即为最终的结果。

小结

以上便是关于位运算的基础入门知识,后续还会继续总结位运算的常见技巧以及实际运用等,希望能和大家多多交流,如有错误之处,也请帮忙指出。

猜你喜欢

转载自blog.csdn.net/qq_41698074/article/details/107592036