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

相关推荐
怀澈1221 小时前
高性能服务器模型之Reactor(单线程版本)
linux·服务器·网络·c++
chnming19871 小时前
STL关联式容器之set
开发语言·c++
带多刺的玫瑰1 小时前
Leecode刷题C语言之统计不是特殊数字的数字数量
java·c语言·算法
爱敲代码的憨仔1 小时前
《线性代数的本质》
线性代数·算法·决策树
威桑1 小时前
MinGW 与 MSVC 的区别与联系及相关特性分析
c++·mingw·msvc
熬夜学编程的小王2 小时前
【C++篇】深度解析 C++ List 容器:底层设计与实现揭秘
开发语言·数据结构·c++·stl·list
yigan_Eins2 小时前
【数论】莫比乌斯函数及其反演
c++·经验分享·算法
Mr.132 小时前
什么是 C++ 中的初始化列表?它的作用是什么?初始化列表和在构造函数体内赋值有什么区别?
开发语言·c++
阿史大杯茶2 小时前
AtCoder Beginner Contest 381(ABCDEF 题)视频讲解
数据结构·c++·算法
C++忠实粉丝2 小时前
计算机网络socket编程(3)_UDP网络编程实现简单聊天室
linux·网络·c++·网络协议·计算机网络·udp