位运算数学意义及应用场景

简介

梳理一下位运算定义、数学意义以及它的应用场景,在日常编码中能给我们带来什么提升。

运算定义

了解原码反码和补码

  • 定义:正数的二进制即为原码,负数的二级制为正数的反码再补码,反码将二进制数按位取反(1变0,0变1),补码对反码加1
  • 案例 -5
原码:00000000 00000000 00000000 00000101
反码:11111111 11111111 11111111 11111010
补码:11111111 11111111 11111111 11111011

<<(左移)

  • 运算规则:
    按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零。
  • 案例: 3 << 2,则是将数字3左移2位
    计算过程:
    3 << 2 首先把3转换为二进制数字0000 0000 0000 0000 0000 0000 0000 0011,然后把该数字高位(左侧)的两个零移出,其他的数字都朝左平移2位,最后在低位(右侧)的两个空位补零。则得到的最终结果是0000 0000 0000 0000 0000 0000 0000 1100,则转换为十进制是12。
  • 数学意义
    如果是10进制向左移动一位,是不是就成了10倍,移两位乘100倍,所以在数字没有溢出的前提下,对于正数和负数,二进制左移左移n位就相当于乘以2的n次方。

>> (带符号右移)

  • 运算规则:
    按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1。
  • 案例11 >> 2,则是将数字11右移2位
    计算过程:
    11 的二进制形式为:0000 0000 0000 0000 0000 0000 0000 1011,然后把低位的最后两个数字移出,因为该数字是正数,所以在高位补零。则得到的最终结果是0000 0000 0000 0000 0000 0000 0000 0010。转换为十进制是2。
  • 数学意义
    右移一位相当于除2,右移n位相当于除以2的n次方(取整)。

>>> (不带符号右移)

  • 运算规则:
    按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),符号位的空位补0,即正数。

&(按位与)

  • 运算规则:将2个操作数都转为二进制,第一个操作数的的第n位与第二个操作数的第n位如果都是1,那么结果的第n为也为1,否则为0
  • 案例 5 & 3
计算过程:
5 转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
3 转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011
计  算  结  果:0000 0000 0000 0000 0000 0000 0000 0001

|(按位或)

  • 运算规则:第一个操作数的的第n位于第二个操作数的第n位 只要有一个是1,那么结果的第n为也为1,否则为0
  • 案例 5 | 3
计算过程:
5 转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
3 转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011
计  算  结  果:0000 0000 0000 0000 0000 0000 0000 0111

^(位异或)

  • 运算规则:第一个操作数的的第n位于第二个操作数的第n位 相反,那么结果的第n为也为1,否则为0
  • 案例 5 & 3
计算过程:
5 转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
3 转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011
计  算  结  果:0000 0000 0000 0000 0000 0000 0000 0110

~(位非即反码)

  • 运算规则:操作数的第n位为1,那么结果的第n位为0,反之为1。
  • ~5
计算过程:
5 转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
计  算  结  果:1111 1111 1111 1111 1111 1111 1111 1010

实际应用

判断奇偶
a&1 == 0 ; //偶数
a&1 == 1;  //奇数
整数平均数
// (x+y)/2可能产生溢出
int average(int x, int y) {   
     return (x&y)+((x^y)>>1);
}
不用临时变量交换两个数
x ^= y;
y ^= x;
x ^= y;
状态标识

商品有多种状态,比如是否支持货到付款、是否虚拟商品、是否预售商品、是否图书商品、是否可开增票等,我们可以用五位的二进制来标识对应的状态,如10010,表示该商品是支持货到付款的图书商品

趣味案例

有 1000 个一模一样的瓶子,其中有 999 瓶是普通的水,有一瓶是毒药。任何喝下毒药的生物都会在一星期之后死亡。现在,你只有 10 只小白鼠和一星期的时间,如何检验出哪个瓶子里有毒药?

  • 把所有的瓶子按照二进制标号,10个老鼠对应二进制10个位,将所有瓶子位的值为1的液体喂给对应位的老鼠,最后将死亡的老鼠组合起二进制数就可以判断哪一瓶是毒药

推荐阅读更多精彩内容