C++位运算
·
1 << i 将1左移 i 位,得到一个只有第 i+1 位为1的数。
n & ~(1 << i) 将 n 的第 i+1 位清零。
m & (1 << i) 从 m 中提取第 i+1 位的值。
(n & ~(1 << i)) | (m & (1 << i)) 将 n 的第 i+1 位替换为 m 的第 i+1 位。
return n ^ (1 << i); 第i位取反
C++位操作
:是处理整数数据类型中位的逻辑操作。以下是一些常用的位操作符及其含义:
-
按位取反 (
~):- 操作符:
~ - 功能:对操作数的每一位取反,即将0变为1,将1变为0。
- 例子:
~0b1010结果为0b0101。
- 操作符:
-
按位与 (
&):- 操作符:
& - 功能:对两个操作数的每一位进行与操作,只有当两位都是1时,结果才为1。
- 例子:
0b1010 & 0b1100结果为0b1000。
- 操作符:
-
按位或 (
|):- 操作符:
| - 功能:对两个操作数的每一位进行或操作,只要有一位是1,结果就为1。
- 例子:
0b1010 | 0b1100结果为0b1110。
- 操作符:
-
按位异或 (
^):- 操作符:
^ - 功能:对两个操作数的每一位进行异或操作,只有当两位不同的时候,结果才为1。
- 例子:
0b1010 ^ 0b1100结果为0b0110。
- 操作符:
-
左移 (
<<):- 操作符:
<< - 功能:将操作数的每一位向左移动指定的位数,左边空出的位填充0。
- 例子:
0b1010 << 2结果为0b101000。
- 操作符:
-
右移 (
>>):- 操作符:
>> - 功能:将操作数的每一位向右移动指定的位数,右边空出的位填充0(对于有符号数,通常是填充符号位)。
- 例子:
0b1010 >> 2结果为0b001。
- 操作符:
-
位清零 (
&=):- 功能:将操作数与另一个操作数进行按位与操作,并将结果赋值给第一个操作数。
- 例子:如果
n = 0b1010,执行n &= 0b1100后,n的值变为0b1000。
-
位设置 (
|=):- 功能:将操作数与另一个操作数进行按位或操作,并将结果赋值给第一个操作数。
- 例子:如果
n = 0b1010,执行n |= 0b1100后,n的值变为0b1110。
-
位异或赋值 (
^=):- 功能:将操作数与另一个操作数进行按位异或操作,并将结果赋值给第一个操作数。
- 例子:如果
n = 0b1010,执行n ^= 0b1100后,n的值变为0b0110。
-
位左移赋值 (
<<=):- 功能:将操作数左移指定的位数,并将结果赋值给操作数。
- 例子:如果
n = 0b1010,执行n <<= 2后,n的值变为0b101000。
-
位右移赋值 (
>>=):- 功能:将操作数右移指定的位数,并将结果赋值给操作数。
- 例子:如果
n = 0b1010,执行n >>= 2后,n的值变为0b001。
这些操作在处理二进制数据、优化算法性能等方面非常有用。
C++位操作符的优先级
,这决定了在表达式中它们被计算的顺序。以下是一些常见运算符的优先级,从高到低排序:
-
后缀运算符:
- 函数调用
() - 子数组访问
[] - 后缀递增/递减
++-- - 成员访问
.->
- 函数调用
-
一元运算符:
- 逻辑非
! - 按位取反
~ - 负号
-(包括位扩展) - 正号
+ - 递增/递减
++--(前缀)
- 逻辑非
-
乘除和模运算符:
- 乘法
* - 除法
/ - 模运算
%
- 乘法
-
加减运算符:
- 加法
+ - 减法
-
- 加法
-
位移运算符:
- 左移
<< - 右移
>>
- 左移
-
关系运算符:
- 大于
> - 小于
< - 大于等于
>= - 小于等于
<=
- 大于
-
相等和不等运算符:
- 等于
== - 不等于
!=
- 等于
-
位与
& -
位异或
^ -
位或
| -
逻辑与
&& -
逻辑或
|| -
条件运算符(三元运算符):
- 条件运算符
?:
- 条件运算符
-
赋值运算符:
- 简单赋值
= - 复合赋值
+=-=*=/=%=<<=>>=&=^=|=
- 简单赋值
-
逗号运算符:
- 逗号
,
- 逗号
了解这些优先级可以帮助你正确地编写和理解复杂的表达式,并在必要时使用括号来改变计算顺序。
例如:
int a = 5, b = 3;
int result = a + b * 2 >> 1;
在这个表达式中,乘法 b * 2 首先被计算,然后是右移 >>,最后是加法 +。这是因为乘法和除法的优先级高于加法和减法,而位移运算符的优先级高于它们。
位操作符的组合及其数学原理
1. 清除特定位
- 操作符:
&= - 数学原理:
- 按位与操作(AND):对于两个位,只有当两个位都是1时,结果才为1,否则为0。
- 掩码:一个特定位为0,其余位为1的数。使用掩码与原数进行按位与操作,可以清除掩码中为0的位。
- 例子:
n &= 0b1111(十进制15)将清除n的第5位及更高位。
2. 设置特定位
- 操作符:
|= - 数学原理:
- 按位或操作(OR):对于两个位,只要有一个位是1,结果就为1,否则为0。
- 掩码:一个特定位为1,其余位为0的数。使用掩码与原数进行按位或操作,可以设置掩码中为1的位。
- 例子:
n |= 0b1000(十进制8)将设置n的第4位为1。
3. 切换特定位
- 操作符:
^= - 数学原理:
- 按位异或操作(XOR):对于两个位,如果两个位相同则结果为0,不同则结果为1。
- 掩码:一个特定位为1,其余位为0的数。使用掩码与原数进行按位异或操作,可以切换掩码中为1的位。
- 例子:
n ^= 0b1000将切换n的第4位。
4. 提取特定位
- 操作符:
& - 数学原理:
- 按位与操作:用于提取特定位的值。通过与掩码进行按位与操作,可以提取掩码中为1的位的值。
- 掩码:一个特定位为1,其余位为0的数。使用掩码与原数进行按位与操作,可以提取掩码对应位的值。
- 例子:
n & 0b1000提取n的第4位。
5. 填充特定位
- 操作符:
| - 数学原理:
- 按位或操作:用于填充特定位的值。通过与掩码进行按位或操作,可以填充掩码中为1的位。
- 掩码:一个特定位为1,其余位为0的数。使用掩码与原数进行按位或操作,可以填充掩码对应位的值。
- 例子:
n | 0b1000将n的第4位及更高位填充为1。
6. 获取补码
- 操作符:
~ - 数学原理:
- 按位取反操作:将一个数的每一位取反,即将0变为1,将1变为0。
- 补码:在计算机中,负数通常以补码的形式存储。对于有符号整数,取反操作可以获取其补码。
- 例子:
~n获取n的补码。
7. 创建掩码
- 操作符:
~ - 数学原理:
- 按位取反操作:通过取反操作创建一个掩码,其中除了某些特定位为0外,其他位均为1。
- 掩码:一个特定位为0,其余位为1的数。使用取反操作可以创建这样的掩码。
- 例子:
~(1 << i)创建一个掩码,其中第i+1位为0,其他位为1。
8. 左移填充
- 操作符:
<<= - 数学原理:
- 左移操作:将一个数的每一位向左移动指定的位数,左边空出的位填充0。
- 位扩展:左移操作可以用于将一个数的值乘以2的幂。
- 例子:
n <<= 2将n左移2位。
9. 右移填充
- 操作符:
>>= - 数学原理:
- 右移操作:将一个数的每一位向右移动指定的位数,右边空出的位填充0(对于有符号数,通常是符号位)。
- 位扩展:右移操作可以用于将一个数的值除以2的幂。
- 例子:
n >>= 2将n右移2位。
10. 获取符号位
- 操作符:
>> - 数学原理:
- 右移操作:通过右移操作获取一个数的符号位。对于有符号整数,符号位是最高位。
- 符号扩展:右移操作可以用于获取一个数的符号。
- 例子:
n >> 31获取n的符号位(对于32位整数)。
11. 交换两个数
- 操作符:
^=,|=,&= - 数学原理:
- 按位异或操作:通过异或操作可以交换两个数的值,而不需要使用额外的变量。
- 步骤:
n ^= m将n和m的值异或,结果存储在n中。m ^= n将m和上一步的结果异或,结果存储在m中,此时m的值变为原始的n。n ^= m将n和上一步的结果异或,结果存储在n中,此时n的值变为原始的m。
- 例子:
n ^= m; m ^= n; n ^= m;
12. 判断奇偶性
- 操作符:
& - 数学原理:
- 按位与操作:通过与1进行按位与操作可以判断一个数的奇偶性。
- 奇偶性:一个数的最低位(LSB)决定了它的奇偶性。奇数的最低位为1,偶数的最低位为0。
- 例子:
n & 1如果结果为1,则n是奇数;如果结果为0,则n是偶数。
这些位操作符的组合在计算机科学和数字逻辑中非常有用,尤其是在需要高效地处理位级数据时。
更多推荐

所有评论(0)