博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
二进制小技巧
阅读量:4184 次
发布时间:2019-05-26

本文共 1580 字,大约阅读时间需要 5 分钟。

x&(x-1)

现在令 x = 10101000,接下来我们算一下 x&(x-1)的结果。

首先我们回忆一下二进制减法的规则

0-0=1-1=0 1-0=1 0-1=1(向高位借位) 例如,(11000011)2-(00101101)2的算式如下: 11000011 被减数 00101101 减数 --1111 借位 (减号是对齐美观用的) ------------------- 10010110 差数

回到刚才的运算,根据二进制减法的规则,我们得:

x-1 = 10100111,
&
x  = 10101000, x & (x-1) = 10100000

我们可以看出,x的最右边的1变成了0,如果我们继续对得到的结果再次执行这样的运算时,发现结果又变为 10000000,由此我们得到结论:x&(x-1) 是将二进制数最右边的1变成0,如果没有1则生成的二进制位全为0。

???

我们看下面程序会输出什么
???

#include
int function(int num){ int count = 0; while(num) { count++; num = num&(num-1); } return count;}int main(){ printf("%d\n",function(888)); return 0;}

答案是:6

  9999的二进制为1101111000,上面的function函数,利用x&(x-1)这个技巧,得到参数num转化为二进制后含1的个数。共有6个1,所以最后的输出结果为6。

我们可以用此式来检查一个无符号数是否是2的幂。

x&(x+1)

令 x = 10101 011,则 x+1 = 10101100,x&(x+1) = 10101 000,

我们看出 x&(x+1) 将一个二进制数最右边0后的1全置为0。可以用来检测一个无符号整数是否为2^n - 1的形式(包括0和所有位均为1的情况)。

(~x)&(x+1)

析出最右侧的0位

例:10100111 -> 00001000

x&(-x)

析出最右侧的1位,如果都没有则生成位均为0的数。

-x  的算法是 对x取反,再加1。
对 x = 01011000,-x = 10101000,x&(-x) = 00001000,即01011000 -> 00001000

  1. 当x为0时,x&(-x) 即 0 & 0,结果为0;
  2. 当x不为0时,x和-x必有一个为正。设x为正。

    1. 当x为奇数时,最后一位为1,取反加1没有进位,故x和-x除最后一位外前面的位正好相反,按位与结果为0,最后一位都为1,故结果为1
    2. 当x为偶数,且为2的m次方(m>0)时,x的二进制表示中只有一位是1(从右往左的第m+1位),其右边有m位0,左边也都是0(个数由表示x的字节数决定),故x取反加1后,从右到左第有m个0,第m+1位及其左边全是1。这样,x& (-x) 得到的就是x
    3. 当x为偶数,却不为2的m次方的形式时,可以写作x= y * (2^k)。其中,y的最低位为1。实际上就是把x用一个奇数左移k位来表示。这时,x的二进制表示最右边有k个0,从右往左第k+1位为1。当对x取反时,最右边的k位0变成1,第k+1位变为0;再加1,最右边的k位就又变成了0,第k+1位因为进位的关系变成了1。左边的位因为没有进位,正好和x原来对应的位上的值相反。二者按位与,得到:第k+1位上为1,左边右边都为0。结果为2^k,即x中包含的2的最大次方的因子。比如x=32(100000)时,其中2的最大次方因子为2^5,结果为32;x=28(11100)时,2的最大次方因子为2^2,结果为4。

转载地址:http://tluoi.baihongyu.com/

你可能感兴趣的文章
evacuate-instance-automatically
查看>>
pycharm常用设置(keymap设置及eclipse常用快捷键总结)
查看>>
关于在openstack的环境变量.bashrc自定自己简化命令
查看>>
Openstack Heat Project介绍(转)
查看>>
How to Perform an Upgrade from Icehouse to Juno(ice升级到juno)
查看>>
高扩展性网站的50条原则(转)-思维导图
查看>>
解决openstack novnc一段时间后自动挂断登录不上问题,novncproxy dead but pid file exists
查看>>
构建OpenStack的云基础架构:ManageIQ(转)
查看>>
云管理软件 ManageIQ(转)
查看>>
CentOS 7.0,启用iptables防火墙(转)
查看>>
svn忽略ignore文件记住方式(转)
查看>>
web缓存相关知识(转)
查看>>
Understanding Spring MVC Model and Session Attributes
查看>>
Spring MVC中Session的正确用法之我见(转)
查看>>
Spring2.5 访问 Session 属性的四种策略
查看>>
Spring MVC 3.0 深入及对注解的详细讲解(转)
查看>>
ModelMap和ModelAndView的作用(转)
查看>>
DISCUZ浅析之COOKIE篇
查看>>
实战DDD(Domain-Driven Design领域驱动设计:Evans DDD)
查看>>
SSH中各个框架的作用以及Spring AOP,IOC,DI详解
查看>>