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

相关推荐
爱编程的鱼25 分钟前
C# 结构(Struct)
开发语言·人工智能·算法·c#
啊我不会诶33 分钟前
CF每日4题
算法
uhakadotcom1 小时前
人工智能如何改变医疗行业:简单易懂的基础介绍与实用案例
算法·面试·github
吴_知遇1 小时前
【华为OD机试真题】428、连续字母长度 | 机试真题+思路参考+代码解析(E卷)(C++)
开发语言·c++·华为od
LaoWaiHang2 小时前
MFC案例:使用键盘按键放大、缩小窗口图像的实验
c++·mfc
山北雨夜漫步2 小时前
机器学习 Day14 XGboost(极端梯度提升树)算法
人工智能·算法·机器学习
到底怎么取名字不会重复2 小时前
Day10——LeetCode15&560
c++·算法·leetcode·哈希算法·散列表
chuxinweihui3 小时前
数据结构——二叉树,堆
c语言·开发语言·数据结构·学习·算法·链表
freexyn3 小时前
Matlab自学笔记五十一:(推荐)输入参数的数量和可变数量的输入
笔记·算法·matlab
陈大大陈3 小时前
基于 C++ 的用户认证系统开发:从注册登录到Redis 缓存优化
java·linux·开发语言·数据结构·c++·算法·缓存