彻底理解位运算 您所在的位置:网站首页 逻辑或与非的用法区别 彻底理解位运算

彻底理解位运算

2024-07-12 09:49| 来源: 网络整理| 查看: 265

目录

与&:

案例如下:

规律如下:

实战案例:

或 |:

案例如下:

规律如下:

实战案例:

异或 ^:

案例如下:

规律如下:

实战案例:

非~:

总结:

与&:

2个二进制进行&操作,只有当2个的数值都为1时,结果才是1。其他均返回0;

案例如下: 15  & 5 = 5 将15和5的二进制分别展示出来

 

由于只有当2个二进制都为1时,结果才为1,其他均为0,所以结果由下图所示。

 

规律如下:

"二进制截断",为何说是二进制截断呢,我们用上面的例子来说,15的二进制低4位都是1,而5的二进制是0101。因为&操作必须都为1结果才是1,所以我们是不是可以理解成5把15的其他位的1给截断成0了呢?那再举个例子,0xFFFF = 65535 = 1111 1111 1111 1111,我们用0x1 = 1 = 0000 0000 0000 0001来进行一个&操作。那么结果是1,也就是把0xFFFF的高31位全部置为0,所以就是用0x1把0xFFFF的高31位都截断为0。

实战案例: 所以在有些偏底层的操作时,为了空间和时间效率,都是用bit位来做标识位代表一些状态,或者表示地址空间。所以当一个32比特位的值可能其中包含了地址空间,已经很多状态标识位。当我们需要把其中某个状态位置为0的时候,我们就可以通过&的操作。假如把第高17位置为0,我们就可以使用1111 1111 1111 1111 0111 1111 1111 1111 & 源操作数,就可以截断第高17位。取余的操作:还记得笔者刚入门程序员的时候,就会做题目来练习,比如遍历1-100,偶数输出什么,奇数输出什么的。其实也就是%2取余的一个操作。那么其实也可以使用&与操作来完成。我们找到其中的规律,当一个十进制转换成二进制后,二进制最后一位为0,要么是0要么就是2的倍数(偶数),反而如果最后一位为1,那么要么是1,要么就是奇数(当然1也是奇数)。所以规律就是:源操作数 & 1,如果为0那么就是偶数,如果为1就是奇数。并且任何数取余都可以,当我们需要取1024的余数时,我们只需要用源操作数 & 1024-1,结果就是1024的余数了,因为1023再加1就是全部进位,所以1023是1024位的所有低位为1,所以通过&操作就可以得出1024的余数(这里笔者,描述能力有点欠佳,大家可以自行测试论证) 或 |:

2个二进制进行 | 操作,只需要2个二进制存在一个1,结果就是1(2个二进制都为1也是1),很好理解,除了2个二进制都为0,其他结果都是1。

案例如下: 10 | 5 = 15

将10和5的二进制分别展示出来

由于只需要2个二进制中存在一个1结果就为1,所以 | 操作后由下图所示。

规律如下:

"二进制组合",这个很好理解,不做多的解释,也就是把2组二进制对齐后组合起来....

实战案例: 上面描述的&操作中的第一个实战案例,说的是怎么用&操作把某个bit位的状态位置为0,那么 | 操作是不是可以把某个比特位置为1呢?毕竟是二进制组合,我们只需要写一组二进制与源操作数对齐后,把状态位需要置为1的哪一位写成1,就大功告成。第2个案例也是基于第一个案例,我们看到Linux2.6内核的源码中(这是fork和clone时,父子进程的配置项,不知道也不影响此案例)。我们在项目中,是不是有很多配置项呢,那么最后如何优雅又高效的管理这些这些配置项呢?没错每个配置对应一组二进制(虽然图中是16进制,进制转换一下就行了么),最后通过 | 操作将这些配置组合起来。判断配置项的时候是不是就可以使用&操作呢(为0就代表没开启某些配置项,点到为止,不过细讲)?

 

异或 ^:

2个二进制 ^异或操作,只要2个二进制相同结果就为0,不相同就为1。(注意这里是判断是否相同,并没有判断是不是又1)

案例如下:

 

规律如下:

"二进制无进位加法",也很好理解,^异或操作是相同为0,不相同为1。而相同的结果只有为11或者00,而11的结果为0,11所以可以理解为二进制做了加法但是没有进位(相加后为0,但是要向高位进1的,但是不进位),而00相加还是为0。而对于不相同的只有10或者01。而01或者10异或操作结果为1,而他们相加也是为1。所以就可以说明异或就是二进制无进位加法。

实战案例: 扰动函数(可以自行百度理解)两数交换,使用^异或操作,可以不借用临时变量。 a = 0011 0010; b = 0010 1010; a = a ^ b; // 运算后a = 0001 1000 b = 0010 1010 b = b ^ a; // 运算后b = 0011 0010 , a = 0001 1000 a = a ^ b; // 运算后a = 0010 1010 , b = 0011 0010 2个相等的数进行^异或操作结果是不是为0,所以可以用来判断是否相等。

非~:

把整个二进制全部取反,0变成1,1变成0。这个太简单了,就不画图理解了。

总结:

找到规律后,就能做到一眼看出答案。

最后,如果本帖对您有一定的帮助,希望能点赞+关注+收藏!您的支持是给我最大的动力,后续会一直更新各种框架的使用和框架的源码解读~!



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有