记录一下位运算(&、|、^、~、>>、<<)

位运算概述

从现代计算机中所有的数据二进制的形式存储在设备中。即 0、1 两种状态。

计算机对二进制数据进行的运算(+、-、*、/)都是叫位运算,即将符号位共同参与运算的运算。

位运算符

符号

描述

运算规则

`&`

两个位都为1时,结果才为1

`|`

两个位都为0时,结果才为0

`^`

异或

两个位相同为0,相异为1

`~`

取反

0变1,1变0

`<<`

左移

各二进位全部左移若干位,高位丢弃,低位补0

`>>`

右移

各二进位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移)

Mark一下

1.与运算符“&”

两个操作数中位都为1,结果才为1,否则结果为0

int a=129;

int b=128;

a 和b 与的结果是:128;

a的值是129,转换成二进制就是10000001.

b的值是128,转换成二进制就是10000000.

只有两个位都是1,结果才是1,结果就是10000000,即128.

2.或运算符“|”

两个位只要有一个为1,那么结果就是1,否则就为0

int a=129;

int b=128;

a 和b 或的结果是:129;

a 的值是129,转换成二进制就是10000001.

b 的值是128,转换成二进制就是10000000.

只有两个位有一个是1,结果才是1,结果就是10000001,即129.

3.非运算符“~”

如果位为0,结果是1,如果位为1,结果是0

int 2

非运算符~2=~原码0000 0000 0000 0010=补码1111 1111 1111 1101

//如果位为0,结果是1,如果位为1,结果是0

补码1111 1111 1111 1101转反码=1111 1111 1111 1100

//[-1] = [10000001]原 = [11111110]反 = [11111111]补

负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1

则负数的反码转补码,符号位不变,最后一位减一

反码1111 1111 1111 1100转原码=1000 0000 0000 0011

结果为-3

4.异或运算符“^”

两个操作数的位中,相同则结果为0,不同则结果为1

int a=15;

int b=2;

a 与 b 异或的结果是:13

a 的值是15,转换成二进制为1111

b 的值是2,转换成二进制为0010

根据异或的运算规律,可以得出其结果为1101 即13

5.移位运算符

  • "<<" 左移运算符,将运算符左边的对象向左移动运算符右边指定的位数(在低位补0)

  1. 例:12 << 2

    首先转化为二进制,12的二进制为0000 1100

    将二进制数向左移两位,低位补0,得到0011 0000

    最后将二进制数转化成十进制数,0011 0000转化为十进制为48

    所以,12 << 2 = 48

  2. 例:-12 << 2

    首先转化为二进制,-12的二进制为1111 0100

    将二进制数向左移两位,低位补0,得到1101 0000

    最后将二进制数转化成十进制数,1101 0000转化为十进制为-48

    所以,-12 << 2 = -48

  • ">>" "有符号"右移运算 符,将运算符左边的对象向右移动运算符右边指定的位数。使用符号扩展机制,也就是说,如果值为正,则在高位补0,如果值为负,则在高位补1.

  1. 例:20 >> 2

    首先转化为二进制,20的二进制为0001 0100

    将二进制数向右移两位,高位补符号位(0),得到0000 0101

    最后将二进制数转化成十进制数,0000 0101转化为十进制为5

    所以,20 >> 2 = 5

  2. 例:-20 >> 2

    首先转化为二进制,20的二进制为1110 1100

    将二进制数向右移两位,高位补符号位(1),得到1111 1011

    最后将二进制数转化成十进制数,1111 1011转化为十进制为-5

    所以,-20 >> 2 = -5

  • ">>>" "无符号"右移运算 符,将运算符左边的对象向右移动运算符右边指定的位数。采用0扩展机制,也就是说,无论值的正负,都在高位补0.

  1. 例:15 >>> 2

    首先转化为二进制,15的二进制为0000 1111

    将二进制数向右移两位,高位补0,得到0000 0011

    最后将二进制数转化成十进制数,0000 0011转化为十进制为3

    所以,15 >>> 2 = 3

    因为负数的符号位(最高位)为1,而无符号右移要在最高位补0,所以32位二进制要写全。带符号右移(>>),高位是补的符号位,前24位都是1。

    (例子中的数比较小,8位足以表示;若是数字很大,要16位才能表示的话,那就是前16位都是1)

    省略掉不影响计算;但这种情况比较特殊,补位和符号位不一样。

  2. 例:-15 >>> 2

    首先转化为二进制,-15的二进制为1111 1111 1111 1111 1111 1111 1111 0001

    将二进制数向右移两位,高位补0,得到0011 1111 1111 1111 1111 1111 1111 1100

    最后将二进制数转化成十进制数,0011 1111 1111 1111 1111 1111 1111 1100转化为十进制为1073741820

    所以,-15 >>> 2 = 1073741820

文章作者: 已删除用户
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Yida
Back-end 算法
喜欢就支持一下吧