位运算符的用法以及用途

本文详细讲解了位操作符、移位操作在二进制中的工作原理,涉及正负数的补码、原码和反码转换,以及如何利用这些概念解决面试题和数值溢出问题。还介绍了将十进制转换为二进制并计数1的方法,以及使用位操作符的高效实现方式。

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

1.记住移位操作符或者位操作符是作用于二进制的补码

正数的原码反码补码都是一样的

负数的反码是原码取反,0变为1,1变为0,注意第一位及符号位保持不变;

          补码是反码加一;


记住位运算符是作用于二进制的

正数的原码反码补码都是一样的 

负数的反码是原码取反,0变为1,1变为0,注意第一位及符号位保持不变;

          补码是反码加一;

 2.左位操作符的用法 <<

假设a,b是整数的话,a << b中a是一个数,b是向右移动几位;

负数变为原码的小技巧:补码取反在加一;跟原码变为补码一样,怎么样容易记吧!!!

按照int四个字节来算,假设a=1,它的补码二进制就是00000000000000000000000000000001,

 -1的补码是1111111111111111111111111111111111111;

+2的补码是00000000000000000000000000000010;

 -2的补码是1111111111111111111111111111111111110;

左移一个位后,它的补码向左移动一个位,即左边丢掉一个数,右边补上一个零;记住符号位不要动;再结合目录1我讲得二进制补码原码转换就可以得出这个结果了

3.右移操作符的用法 >>

右移一个位后,它的补码向右移动一个位,即右边丢掉一个数,左边补上一个零;记住符号位不要动;再结合目录1我讲得二进制补码原码转换就可以得出这个结果了

右移是算术右移,所以不动符号位;逻辑右移是将符号位也动了

+4的补码是00000000000000000000000000000100;

 -4的补码是1111111111111111111111111111111111100;

+2的补码是00000000000000000000000000000010;

 -2的补码是1111111111111111111111111111111111110;

4.按位于 &操作符的用法

a & b 的意思是将补码中一一对应的位,如果全为1就为1,反之为0;

5的补码:00000000000000000000000000000101

7的补码:00000000000000000000000000000111

5&7补码   00000000000000000000000000000101

那么5 & 7等于5;

5.按位或的用法

a | b 的意思是将补码中一一对应的位,如果全为0就为0,反之为1;

5的补码:00000000000000000000000000000101

7的补码:00000000000000000000000000000111

5 | 7补码   00000000000000000000000000000111

那么5 | 7等于7;

6.按位异或的用法

a | b 的意思是将补码中一一对应的位,如果相同就是0,相反就是1;

5的补码:00000000000000000000000000000101

7的补码:00000000000000000000000000000111

5 ^ 7补码   0000000000000000000000000000010

5 ^ 7 = 2

7.按位取反的用法

~a的用法是将二进制的数值全部取反(包括符号值)

1的补码是00000000000000000000000000000001

-2的补码111111111111111111111111111111111110

~1的补码是111111111111111111111111111111111110

所以 ~1等于 -2 

我们将移位操作符和位操作符讲完了,接下来我们来讲一下它们的用途

它们通常用于二进制中,但也有别的情景;

8.移位操作符和位操作符的用途

曾经出现过一道变态的面试题

如何不创建第三个变量来交换两个变量的值?

这道题可谓难倒了大部分人;

但是也有人解决了它

但是这么写也有缺陷,有可能两数相加的值过大,导致超出最大值;

因此,咱们结合前面我们讲得,可以考虑另一种做法;

首先我们讲一下底层逻辑:

a ^ a = 0;

a ^ 0 = a;

接下来咱们来实现交换它们:

这样写就不会导致数值溢出了;

但是这种做法也仅仅适用于面试,正常情况下直接建立一个变量就行了,因为那样更具有可读性;

接下来你会怎么考虑将一个十进制转换为二进制并且打印二进制的1的个数呢?

我接下来先讲一种思路

例如11的二进制有多少个1?

首先我们可以算出它的补码,11%2=1 ,11/2=5, 5%2=1, 5/2=2,  2%2 =0,  2/2=1, 1%2=1,  1/2=0,然后从右往左用它的余数就是他的补码1011。这个方法适用于所有数,数越大越好用。

接下来我们来用代码实现一下

当然我们也可以用刚刚讲的位操作符来实现它们

底层逻辑:减去n的补码中1的值,例如1000 &(0111)= 0;

n = 15的补码是1111

n &(n-1)即

1111 - n

1110 - n-1

1101 - n  // 即1111&1110

1100 - n-1

1100 - n

1011 - n-1

1000 - n

0111 - n-1

0000 - n

好了讲到这里就差不多的结束了,让我们享受连续不断发生的奇迹(指日常)。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值