二进制位交换 反转 计数


如何交换一个整形数的二进制表示的其中两位.

比如要把a,与b进行交换。那么方法如下:x表示任意值。

xxxx xxxx xxxx xaxx xxxx xxbx xxxx xxxx


分为两步:

第一步:首先要求得

xxxx xxxx xxxx x0xx xxxx xx0x xxxx xxxx

第二步:在第一步的基础上加上:

0000 0000 0000 0b00 0000 00a0 0000 0000



第一步的代码可以写做:两位置值表示为x, y。数值表示为v

ret = v & (~(1<<x)) & (~(1<<y))

第二步代码:

ret = ret | (((v>>y)&1)<<x) | (((v>>x)&1)<<y);

总结一下代码,写做

这里粘个代码

void _swap(unsigned int &v, int x, int y)
{
	//思路:第一步先减去0000x0000,再减去00000y0000;
	//      第二步先加上000y0000,再加上0000x0000;
	//	    可以一句话完成.

	//说明思路的代码:
	//unsigned int x_pos = ((v>>y)&1)<<x;
	//unsigned int y_pos = ((v>>x)&1)<<y;
	//unsigned int x_value = ((v>>x)&1)<<x;
	//unsigned int y_value = ((v>>y)&1)<<y;
	//v -= (x_value + y_value);
	//v += (x_pos + y_pos);
	//print_int(v);


	//终极版:
	//一句话也可以完成。
	v = v & (~(1<<x)) & (~(1<<y)) | (((v>>y)&1)<<x) | (((v>>x)&1)<<y);
}

如何把二进制位按中间对折

比如100对折之后成为001。

不过这里的长度要求是32位的。也就是31位与0位互换,以此类推。

这里就不多说了,《代码之美》一书中提供了一种分治的思想来进行1位计数。这里同样利用这种分治思想来处理

unsigned int bit_reverse(unsigned int n)
{
	n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa);
	n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc);
	n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0);
	n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00);
	n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000);
	return n;
}
看一下对char的处理

unsigned char ReverseBits(unsigned char ch)
{
ch = (ch &0x55) <<1| (ch >>1) &0x55;
ch = (ch &0x33) <<2| (ch >>2) &0x33;
ch = (ch &0x0F) <<4| (ch >>4) &0x0F;
return ch;
}
先看看0x55,0x33,0x0F的二进制
0x55 -> 01010101 B
0x33 -> 00110011 B
0x0F -> 00001111 B
从中可以看出,是先将相连的两bits对调实现相连2 bits数据翻转;

接着两个相连的“2 bits组合”对调实现相连4 bits数据翻转;

再下来就是将两个相连的“4 bits组合”对调即可以完成对一个字符8 bits的翻转。

对于更多bytes 的数据做同样的处理。单数个bits呢,这个就需要思考一下了。


如何对整形数计算1的个数

《编程之美》上面的代码其实并不高效,这里给个《代码之美》中猛的代码

int cnt(unsigned int x)
{
	x = x - ((x>>1)&0x55555555);
	x = (x & 0x33333333) + ((x>>2)&0x33333333);
	x = (x + (x>>4)) & 0x0f0f0f0f;
	x = (x + (x>>8));
	x = (x + (x>>16));
	return x&0x3f;
}

做这个处理有一个经典的方法,分治策略( divide and conquer strategy ),该方法来源于Henry S.Warren 的《Hacker's Delight》对Reversing Bits 的介绍。



  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值