在讨论位运算之前有必要补充一下计算机底层使用的编码表示,计算机内部存储、计算的任何信息都是由二进制(0和1)表示,而二进制有三种不同的表示形式:原码、反码和补码。计算机内部使用补码来表示。
原码,就是其二进制表示(注意,有一位符号位)
反码,正数的反码就是原码,负数的反码是符号位不变,其余位取反
补码,正数的补码就是原码,负数的补码是反码+1
符号位,最高位为符号位,0表示正数,1表示负数。在位运算中符号位也参与运算。
按位与操作 &
1
&
1
=
1
1
&
0
=
0
0
&
1
=
0
0
&
0
=
0
例如:3 & 17 = 1
3=00000011
17=00010001
&=00000001
按位或操作 |
1
&
1
=
1
1
&
0
=
1
0
&
1
=
1
0
&
0
=
0
例如:3 | 17 = 1
3=00000011
17=00010001
|=00010011
左移操作 <<
左移操作 << 是把操作数整体向左移动,左移操作是二目运算符。
例如:33 << 2 = 100001 << 2 = 10000100 = 132
-2147483647 << 1 = 10000000000000000000000000000001 << 1 = 10 = 2 (符号位也参与运算)
技巧:a << n = a * 2^n (a为正数)
右移操作 >>
右移操作 >> 是把操作数整体向右移动,右移操作是二目运算符。
例如:33 >> 2 = 100001 >> 2 = 001000 = 8
-2147483647 >> 1 = 10000000000000000000000000000001 << 1 = 11000000000000000000000000000000 = -1073741824 (符号位也参与运算,补足符号位)
技巧:a >> n = a / 2^n (a为正数)
1
^ 1
=
0
1
^
0
=
1
0
^
1
=
1
0
^
0
=
0
例如:33 ^ 12 = 45
33=00100001
12=00001100
^ = 00101101
技巧:异或是不进位加法,两个数做加法,把进位舍去