几有趣的位运算技巧

今天ICS课上讲了两个很有趣的位运算技巧。

题目1,你要实现一个函数

unsigned leftmost(unsigned x);

返回x的最大一位1。

我们都知道最小可以用x&-x来实现,但是最大要怎么实现呢,感觉应该没有能够左右翻转的位运算。

所以基本可以用类似二分的做法来做。

然后老师给出了一种常数非常小的做法。

unsigned leftmost(unsigned x){
	x|=x>>1;
	x|=x>>2;
	x|=x>>4;
	x|=x>>8;
	x|=x>>16;
	return x&((x>>1)+1);
}

题目2
实现一个函数,判断x位的奇偶性。
还是用同样的方法

int evenones(unsigned x){
	x^=x>>16;
	x^=x>>8;
	x^=x>>4;
	x^=x>>2;
	x^=x>>1;
	return (x&1)^1;
}

题目3
求popcount(x),采用了分块的思想,分成8个大小为4的块

int popcount(int x){
	int mask=(1<<4)+1;
	mask|=mask<<8;
	int mask2=(mask<<16)|mask;
	int s=0;
	s+=x&mask2;
	s+=(x>>1)&mask2;
	s+=(x>>2)&mask2;
	s+=(x>>3)&mask2;
	int mask3=3|(3<<16);
	int ss=0;
	ss+=s&mask3;
	ss+=(s>>4)&mask3;
	ss+=(s>>8)&mask3;
	ss+=(s>>12)&mask3;
	return (ss&31)+((ss>>16)&31);
}
	

上述代码可能存在问题(纯手打,没有测过),请大家以借鉴思路为主。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值