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

# 位运算概述

从现代计算机中所有的数据二进制的形式存储在设备中。即 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

Last Updated: 12/5/2021, 10:57:53 PM