位运算
一、概述
运算符 | 描述 | 运算规则 |
---|---|---|
& | 与 | 两位都为1时,结果为1 |
| | 或 | 两位都为0时,结果为0 |
^ | 异或 | 两位相同为0,相异为1 |
~ | 取反 | 0变1,1变0 |
>> | 右移 | 各位右移若干位,对于无符号数高位补0,有符号数各编译器处理方法不一,或补符号位(算术右移),或补0(逻辑右移) |
<< | 左移 | 各位全部左移若干位,高位丢弃,低位补0 |
运算优先级:~
> >>, <<
> &
> ^
> |
二、技巧
1、与
1)清零
int n = 10; n &= 0;
2)奇偶判断
int n = 10; if((n & 1) == 0) { std::cout << "偶数\n"; } else { std::cout << "奇数\n"; }
3)取位
例:现有十进制数174(二进制为1010 1110),若想得到其后四位,则将它与第4位为1,其他位为0的数(即二进制数0000 1111,十进制数15)进行与运算,结果为十进制数14(二进制为0000 1110)。
int n = 174; n &= 15; // n = 14
2、或
1)将指定位设为1
例:现有十进制数174(二进制为1010 1110),若想将其低4位设为1,则将其与二进制数0000 1111(十进制数15)进行或运算,结果为十进制数175(二进制为1010 1111),若想将某位设为1,则或某个数,这个数这一位为1其他都为0。
int n = 174; n |= 15; // n = 175 n = 174; n |= 16; // n = 190(二进制:1011 1110)
PS:不同于与运算,我们很少用或运算进行任意位赋值。通常来讲,我们只使用n | 1
把 n 的最后一位强行变成 1,其实质意义是把原数加一。或者使用a | 1 - 1
再把它变为 0,这个技巧通常用于把 n 变成 n 最接近的偶数。
3、异或
异或符合以下几条性质:
① 交换律
② 结合律 (a ^ b) ^ c = a ^ (b ^ c)
③ 对于任何数 n,都有n ^ n = 0
和n ^ 0 = n
④ 自反性 a ^ b ^ b = a ^ 0 = a
1)翻转指定位
例:现有十进制数174(二进制为1010 1110),若想翻转其低4位,则将其与二进制数0000 1111(十进制数15)进行异或运算(低4位为1,其他都为0),结果为十进制数161(二进制为1010 0001);若想翻转某一位,则异或一个数,这个数这一位为1其他都为0。
int n = 174; n ^= 15; // n = 161 n = 174; n ^= 16; // n = 190(二进制:1011 1110)
4、取反
1)与 & 运算配合使一个数最低位为0
int n = 175; // 二进制:1010 1111 n = (n & ~ 1); // n = 174
5、右移
1)除法优化
a >> b
本质为a / pow(2, b)
int a = 16; int b = 1; a >>= b; // a = 16 / 2 = 8 a = 16; b = 2; a >>= b; // a = 16 / (2 * 2) = 4
6、左移
1)乘法优化
a << b
本质为a * pow(2, b)
int a = 2; int b = 1; a <<= b; // a = 2 * 2 = 4 a = 2; b = 2; a <<= b; // a = 2 * (2 * 2) = 8
三、拓展
1、计算一个数二进制中1的个数
// 方法一 int CountOf1(int num) { int count = 0; unsigned int flag = 1; while(flag) { if(num & flag) { ++count; } flag = flag << 1; } return count; } // 方法二 int CountOf1(int num) { int count = 0; while(num) { num &= num - 1; ++count; } return count; }
2、判断一个数是否为2的n次方
bool Is2Power(int num) { num &= num - 1; if(num) { return false; } return true; }
3、获得最大int值
int GetMaxInt() { return ((unsigned int)-1) >> 1; }
4、获得最小int值
int GetMinInt() { return 1 << 31; }
5、交换两个数(不使用临时变量)
void Swap(int &a, int &b) { a ^= b; b ^= a; a ^= b; }
6、求一个数的绝对值
int Abs(int n) { return (n ^ n >> 31) - (n >> 31); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现