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++位操作

:是处理整数数据类型中位的逻辑操作。以下是一些常用的位操作符及其含义:

  1. 按位取反 (~):

    • 操作符:~
    • 功能:对操作数的每一位取反,即将0变为1,将1变为0。
    • 例子:~0b1010 结果为 0b0101。
  2. 按位与 (&):

    • 操作符:&
    • 功能:对两个操作数的每一位进行与操作,只有当两位都是1时,结果才为1。
    • 例子:0b1010 & 0b1100 结果为 0b1000。
  3. 按位或 (|):

    • 操作符:|
    • 功能:对两个操作数的每一位进行或操作,只要有一位是1,结果就为1。
    • 例子:0b1010 | 0b1100 结果为 0b1110。
  4. 按位异或 (^):

    • 操作符:^
    • 功能:对两个操作数的每一位进行异或操作,只有当两位不同的时候,结果才为1。
    • 例子:0b1010 ^ 0b1100 结果为 0b0110。
  5. 左移 (<<):

    • 操作符:<<
    • 功能:将操作数的每一位向左移动指定的位数,左边空出的位填充0。
    • 例子:0b1010 << 2 结果为 0b101000。
  6. 右移 (>>):

    • 操作符:>>
    • 功能:将操作数的每一位向右移动指定的位数,右边空出的位填充0(对于有符号数,通常是填充符号位)。
    • 例子:0b1010 >> 2 结果为 0b001。
  7. 位清零 (&=):

    • 功能:将操作数与另一个操作数进行按位与操作,并将结果赋值给第一个操作数。
    • 例子:如果 n = 0b1010,执行 n &= 0b1100 后,n 的值变为 0b1000。
  8. 位设置 (|=):

    • 功能:将操作数与另一个操作数进行按位或操作,并将结果赋值给第一个操作数。
    • 例子:如果 n = 0b1010,执行 n |= 0b1100 后,n 的值变为 0b1110。
  9. 位异或赋值 (^=):

    • 功能:将操作数与另一个操作数进行按位异或操作,并将结果赋值给第一个操作数。
    • 例子:如果 n = 0b1010,执行 n ^= 0b1100 后,n 的值变为 0b0110。
  10. 位左移赋值 (<<=):

    • 功能:将操作数左移指定的位数,并将结果赋值给操作数。
    • 例子:如果 n = 0b1010,执行 n <<= 2 后,n 的值变为 0b101000。
  11. 位右移赋值 (>>=):

    • 功能:将操作数右移指定的位数,并将结果赋值给操作数。
    • 例子:如果 n = 0b1010,执行 n >>= 2 后,n 的值变为 0b001。

这些操作在处理二进制数据、优化算法性能等方面非常有用。

C++位操作符的优先级

,这决定了在表达式中它们被计算的顺序。以下是一些常见运算符的优先级,从高到低排序:

  1. 后缀运算符:

    • 函数调用 ()
    • 子数组访问 []
    • 后缀递增/递减 ++ --
    • 成员访问 . ->
  2. 一元运算符:

    • 逻辑非 !
    • 按位取反 ~
    • 负号 -(包括位扩展)
    • 正号 +
    • 递增/递减 ++ --(前缀)
  3. 乘除和模运算符:

    • 乘法 *
    • 除法 /
    • 模运算 %
  4. 加减运算符:

    • 加法 +
    • 减法 -
  5. 位移运算符:

    • 左移 <<
    • 右移 >>
  6. 关系运算符:

    • 大于 >
    • 小于 <
    • 大于等于 >=
    • 小于等于 <=
  7. 相等和不等运算符:

    • 等于 ==
    • 不等于 !=
  8. 位与 &

  9. 位异或 ^

  10. 位或 |

  11. 逻辑与 &&

  12. 逻辑或 ||

  13. 条件运算符(三元运算符):

    • 条件运算符 ?:
  14. 赋值运算符:

    • 简单赋值 =
    • 复合赋值 += -= *= /= %= <<= >>= &= ^= |=
  15. 逗号运算符:

    • 逗号 ,

了解这些优先级可以帮助你正确地编写和理解复杂的表达式,并在必要时使用括号来改变计算顺序。

例如:

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. 交换两个数

  • 操作符:^=, |=, &=
  • 数学原理:
    • 按位异或操作:通过异或操作可以交换两个数的值,而不需要使用额外的变量。
    • 步骤:
      1. n ^= m 将n和m的值异或,结果存储在n中。
      2. m ^= n 将m和上一步的结果异或,结果存储在m中,此时m的值变为原始的n。
      3. n ^= m 将n和上一步的结果异或,结果存储在n中,此时n的值变为原始的m。
    • 例子:
      n ^= m;
      m ^= n;
      n ^= m;
      

12. 判断奇偶性

  • 操作符:&
  • 数学原理:
    • 按位与操作:通过与1进行按位与操作可以判断一个数的奇偶性。
    • 奇偶性:一个数的最低位(LSB)决定了它的奇偶性。奇数的最低位为1,偶数的最低位为0。
    • 例子:n & 1 如果结果为1,则n是奇数;如果结果为0,则n是偶数。

这些位操作符的组合在计算机科学和数字逻辑中非常有用,尤其是在需要高效地处理位级数据时。

更多推荐