位运算

本文介绍了六种位运算符的功能及使用方法,并提供了多种实际应用场景,包括不使用临时变量交换两个数、计算平均值避免溢出等。还详细说明了如何判断一个数是否为2的幂、判断奇偶性、计算二进制中1的个数等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先膜拜Matrix67大牛~http://www.matrix67.com/blog/

1.       六种位运算符

&:清零特定位,x &= ~(1<<k);

   取特定位,x & (1<<k)

|: 置1特定位,x |= 1<<k;

^: 取反特定位,x &= 1<<k;

~: 生成全1掩码,~0

<< 

>>:算术右移,-2>>1得到-1-1>>1仍是-1java中有单独的逻辑右移>>>)(标准未规定是算术移位,但一般都是)

建议位运算都使用unsigned类型unsigned int x = 1U<<31; (unsigned int 也可简写为unsigned)

移位数会mod W,其中W为数据类型长度,因此<<32等于未移位。

 

2.       应用

(1)不用temp交换两个数

X ^= y;   y ^= x;   x ^= y;

可看做y = x^x^y;   x = x^(y^y);

而用a = a+b; b = a-b; a = a-b;可能会溢出

 

(2)求两数的平均值

(x&y) + ((x^y)>>1)

(x+y)/2可能溢出

 

(3)判断一个数是否2的幂

!(X & (x-1)) && x

x & (x-1) 消掉x最末尾的1

 

(4)判断奇偶

X & 1    等于1为奇

 

(5)判断二进制表示中1的个数的奇偶性,奇偶校验

x ^= x>>1; //每一位表示该位和前一位中1的个数的奇偶性

x ^= x>>2; //每一位表示前4位中1的个数的奇偶性

x ^= x>>4;

x ^= x>>8;

x ^= x>>16; //最后一位表示所有32位中1的个数的奇偶性

bool r = x&1;

r = 1表示有奇数个1

 

(6)计算二进制表示中1的个数

x = (x & 0x55555555) + ((x>>1) & 0x55555555);//将第12位的数字相加放回1,2

x = (x & 0x33333333) + ((x>>2) & 0x33333333);

x = (x & 0x0F0F0F0F) + ((x>>4) & 0x0F0F0F0F);

x = (x & 0x00FF00FF) + ((x>>8) & 0x00FF00FF);

x = (x & 0x0000FFFF) + ((x>>16) & 0x0000FFFF);

 

(7)计算二进制表示中前导0的个数 (二分法)

int n=0;

if ((x >> 16) == 0) {n += 16; x <<= 16;}

if ((x >> 24) == 0) {n += 8; x <<= 8;}

if ((x >> 28) == 0) {n += 4; x <<= 4;}

if ((x >> 30) == 0) {n += 2; x <<= 2;}

if ((x >> 31) == 0) {n += 1; x <<= 1;}

n += !(x >> 31); //!0 等于1

看了Matrix67博客的留言才意识到n = n+16; 应该写成n += 16;才像话

 

3.       位域

struct BS{

unsigned int a:3;

int b:3;

};

bs.a = 7;         bs.b = 7;

cout<<bs.a<<bs.b<<endl;

结果为7 -1,单个位域也分有符号无符号数

 

4.       C++标准库 bitset

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值