位运算

一、概述

运算符 描述 运算规则
& 两位都为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 = 0n ^ 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);
}
posted @   HOracle  阅读(66)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示