C++中的‘位’操作

目录

摘要

基本位操作

[1. 按位与(AND)`&`:](#1. 按位与(AND)&:)

[2. 按位或(OR)`|`:](#2. 按位或(OR)|:)

[3. 按位异或(XOR)`^`:](#3. 按位异或(XOR)^:)

[4. 按位取反(NOT)`~`:](#4. 按位取反(NOT)~:)

[5. 左移(Left Shift)`<<`:](#5. 左移(Left Shift)<<:)

高级用法

[1. 快速乘除以2的幂:](#1. 快速乘除以2的幂:)

[2. 交换两个数(不使用临时变量):](#2. 交换两个数(不使用临时变量):)

[3. 检测奇偶性:](#3. 检测奇偶性:)

[4. 清除最低位的1:](#4. 清除最低位的1:)

[5. 获取最低位的1:](#5. 获取最低位的1:)

[6. 统计二进制中1的个数:](#6. 统计二进制中1的个数:)

[7. 快速判断是否是2的幂:](#7. 快速判断是否是2的幂:)

与宏定义结合

[1. 设置某一位:](#1. 设置某一位:)

[2. 清除某一位:](#2. 清除某一位:)

[3. 切换某一位:](#3. 切换某一位:)

[4. 检查某一位是否为1:](#4. 检查某一位是否为1:)

[5. 计算二进制中1的个数:](#5. 计算二进制中1的个数:)

总结


摘要

在C++中,位操作可以通过位与(AND )、位或(OR )、位异或(XOR )、位取反(NOT )、左移(Left Shift )和右移(Right Shift)等操作来实现。如果结合宏定义来使用,可以使位操作更加简洁。

基本位操作

1. 按位与(AND )`&`:

每个位进行与运算,只有对应位都为1时,结果位才为1。

cpp 复制代码
int a = 5;  // 0101
int b = 3;  // 0011
int result = a & b;  // 0001 -> 1

2. 按位或(OR )`|`:

每个位进行或运算,只要对应位有一个为1,结果位就为1。

cpp 复制代码
int a = 5;  // 0101
int b = 3;  // 0011
int result = a | b;  // 0111 -> 7

3. 按位异或(XOR )`^`:

cpp 复制代码
int a = 5;  // 0101
int b = 3;  // 0011
int result = a ^ b;  // 0110 -> 6

每个位进行异或运算,对应位相同为0,不同为1。

4. 按位取反(NOT )`~`:

将每个位取反,0变1,1变0。

cpp 复制代码
int a = 5;  // 0101
int result = ~a;  // 1010 -> -6(在补码表示中)

5. 左移(Left Shift)`<<`:

将二进制数的所有位向左移动指定的位数,右边补0。

cpp 复制代码
int a = 5;  // 0101
int result = a << 1;  // 1010 -> 10
  1. 右移(Right Shift )`>>`:

将二进制数的所有位向右移动指定的位数,左边补符号位(算术右移)或0(逻辑右移)。

cpp 复制代码
int a = 5;  // 0101
int result = a >> 1;  // 0010 -> 2

高级用法

1. 快速乘除以2的幂:

左移操作相当于乘以2的幂,右移操作相当于除以2的幂。

cpp 复制代码
int a = 5;
int result = a << 3;  // 相当于 a * 8 -> 40
result = a >> 2;  // 相当于 a / 4 -> 1

2. 交换两个数(不使用临时变量):

可以使用异或操作来交换两个数。

cpp 复制代码
int a = 5;
int b = 3;
a = a ^ b;
b = a ^ b;
a = a ^ b;
// 现在 a = 3, b = 5

3. 检测奇偶性:

使用按位与操作来检测一个数是奇数还是偶数。

cpp 复制代码
int a = 5;
bool isOdd = a & 1;  // 如果 a 的最后一位是1,则是奇数

4. 清除最低位的1:

通过 `x & (x - 1)` 可以清除最低位的1。

cpp 复制代码
int a = 12;  // 1100
int result = a & (a - 1);  // 1000 -> 8

5. 获取最低位的1:

使用 `x & -x` 可以获取最低位的1。

cpp 复制代码
int a = 12;  // 1100
int result = a & -a;  // 0100 -> 4

6. 统计二进制中1的个数:

可以通过反复清除最低位的1来统计一个整数中1的个数。

cpp 复制代码
int countOnes(int x) {
    int count = 0;
    while (x) {
        x = x & (x - 1);
        count++;
    }
    return count;
}

7. 快速判断是否是2的幂:

一个数如果是2的幂,则它的二进制表示中只有一个1。

cpp 复制代码
bool isPowerOfTwo(int x) {
    return x > 0 && (x & (x - 1)) == 0;
}

与宏定义结合

通过将位操作与宏定义结合,可以提高代码的可读性和可维护性,同时保留位操作的高效性。

1. 设置某一位:

cpp 复制代码
#define SET_BIT(x, pos) ((x) | (1 << (pos)))
int x = 5;  // 0101
x = SET_BIT(x, 1);  // 设置第1位 -> 0111 -> 7

2. 清除某一位:

cpp 复制代码
#define CLEAR_BIT(x, pos) ((x) & ~(1 << (pos)))
int x = 7;  // 0111
x = CLEAR_BIT(x, 1);  // 清除第1位 -> 0101 -> 5

3. 切换某一位:

cpp 复制代码
#define TOGGLE_BIT(x, pos) ((x) ^ (1 << (pos)))
int x = 5;  // 0101
x = TOGGLE_BIT(x, 1);  // 切换第1位 -> 0111 -> 7
x = TOGGLE_BIT(x, 1);  // 再次切换第1位 -> 0101 -> 5

4. 检查某一位是否为1:

cpp 复制代码
#define CHECK_BIT(x, pos) ((x) & (1 << (pos)))
int x = 5;  // 0101
bool isSet = CHECK_BIT(x, 2);  // 检查第2位 -> 0100 -> true

5. 计算二进制中1的个数:

cpp 复制代码
#define COUNT_ONES(x) ({ \
    int count = 0; \
    int n = (x); \
    while (n) { \
        n &= (n - 1); \
        count++; \
    } \
    count; \
})
int x = 15;  // 1111
int onesCount = COUNT_ONES(x);  // 4

总结

在C++中使用位操作一定需要注意自己的需求是什么,对位操作一定要仔细,否则很容易出现问题。同时,通过位操作可以优化代码,并且如果有涉及到一些算法的地方,也可以用位操作来优化算法,提高整体性能。

相关推荐
passer__jw7679 分钟前
【LeetCode】【算法】283. 移动零
数据结构·算法·leetcode
Ocean☾15 分钟前
前端基础-html-注册界面
前端·算法·html
顶呱呱程序23 分钟前
2-143 基于matlab-GUI的脉冲响应不变法实现音频滤波功能
算法·matlab·音视频·matlab-gui·音频滤波·脉冲响应不变法
爱吃生蚝的于勒1 小时前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法
羊小猪~~1 小时前
数据结构C语言描述2(图文结合)--有头单链表,无头单链表(两种方法),链表反转、有序链表构建、排序等操作,考研可看
c语言·数据结构·c++·考研·算法·链表·visual studio
王哈哈^_^1 小时前
【数据集】【YOLO】【VOC】目标检测数据集,查找数据集,yolo目标检测算法详细实战训练步骤!
人工智能·深度学习·算法·yolo·目标检测·计算机视觉·pyqt
星沁城1 小时前
240. 搜索二维矩阵 II
java·线性代数·算法·leetcode·矩阵
脉牛杂德2 小时前
多项式加法——C语言
数据结构·c++·算法
legend_jz2 小时前
STL--哈希
c++·算法·哈希算法
CSUC2 小时前
【C++】父类参数有默认值时子类构造函数列表中可以省略该参数
c++