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

相关推荐
机器视觉知识推荐、就业指导9 分钟前
Qt/C++事件过滤器与控件响应重写的使用、场景的不同
开发语言·数据库·c++·qt
muyierfly12 分钟前
34.贪心算法1
算法·贪心算法
孤寂大仙v17 分钟前
【C++】STL----list常见用法
开发语言·c++·list
咩咩大主教1 小时前
C++基于select和epoll的TCP服务器
linux·服务器·c语言·开发语言·c++·tcp/ip·io多路复用
luthane3 小时前
python 实现average mean平均数算法
开发语言·python·算法
静心问道3 小时前
WGAN算法
深度学习·算法·机器学习
Ylucius3 小时前
动态语言? 静态语言? ------区别何在?java,js,c,c++,python分给是静态or动态语言?
java·c语言·javascript·c++·python·学习
是店小二呀3 小时前
【C++】C++ STL探索:Priority Queue与仿函数的深入解析
开发语言·c++·后端
杰九3 小时前
【算法题】46. 全排列-力扣(LeetCode)
算法·leetcode·深度优先·剪枝
ephemerals__3 小时前
【c++】动态内存管理
开发语言·c++