1、位运算语法
计算机中所有的数据都是以二进制的形式存储在设备中。即 0、1 两种状态,计算机对二进制数据进行的运算(+、-、、/)都是叫位运算,相比在代码中直接使用(+、-、、/)运算符,合理的运用位运算更能显著提高代码在机器上的执行效率。
举一个简单的例子来看下 CPU 是如何进行计算的,比如这行代码:
int a = 35;
int b = 47;
int c = a + b;
计算两个数的和,因为在计算机中都是以二进制来进行运算,所以上面我们所给的 int 变量会在机器内部先转换为二进制在进行相加:
35: 0 0 1 0 0 0 1 1
47: 0 0 1 0 1 1 1 1
————————————————————
82: 0 1 0 1 0 0 1 0
按位与(&):
- 两个对应的位都是1时结果才为1,否则为0。
- 示例:5 & 3 = 1(即 0101 & 0011 = 0001)
按位或(|):
- 两个对应的位中只要有一个是1,结果就为1。
- 示例:5 | 3 = 7(即 0101 | 0011 = 0111)
按位异或(^):
- 两个对应的位不同则结果为1,相同则结果为0。
- 示例:5 ^ 3 = 6(即 0101 ^ 0011 = 0110)
按位取反(~):
- 将每个位上的1变成0,0变成1。
- 示例:~5 = -6(在有符号整数中,二进制表示会有所不同,取决于补码表示法)
左移(<<):
- 将所有位向左移动指定的位数,右边空出的位置用0填充。
- 示例:5 << 1 = 10(即 0101 << 1 = 1010)
右移(>>):
- 将所有位向右移动指定的位数,左边空出的位置根据整数是有符号还是无符号来填充0或原最高位的值。
- 示例:5 >> 1 = 2(即 0101 >> 1 = 0010)
2、位运算常用场景
(1)交换两个数的值
交换ab的值,原理就是ab异或之后得到c 然后c和其中任意一位数异或得到另外一位
a:11011
b:10100
a = a ^ b # 第一次异或a变成两个数的结果,b没变
b = b ^ a # b 异或他们的结果得到a
a = a ^ b
(2)快速判断奇偶性
使用按位与运算可以快速判断一个整数是否为偶数。由于任何偶数的二进制表示最后一位都是0,而奇数最后一位是1,
- 因此可以使用 n & 1 的结果来判断:
- 如果结果为0,则n是偶数。
- 如果结果为1,则n是奇数。
(3)判断整数是否为2的幂
一个正整数如果是2的幂,那么它在二进制表示中仅有一位为1,其余位都为0。例如,8(即1000)是2的幂。你可以通过将该数与其减1后的数做按位与运算来判断:
- 如果 n & (n - 1) 的结果为0,并且n不为0,那么n是2的幂。
(4)实现快速乘法和除法
利用左移和右移运算可以实现快速的乘法和除法:
- 左移一位相当于乘以2。
- 右移一位相当于除以2。