此章所讲都是涉及整数运算在计算机中以二进制的形式进行运算 ,在二进制层面刨析整数在计算机中的计算。
1.移位操作符
<<左移操作符
>>右移操作符
注:移位操作符只能对整数进行操作,不能对小数进行操作
1.1左移操作符
移位规则:左边多出去的抛弃,右边补0。
先给出一个例子:
由上图可得,n向左移一位之后,值变为了20。以下为它的原理 :
左移一位之后,将多出来的一位个丢弃,然后补上0,所以值变为了20。
1.2右移操作符
移位规则:1.逻辑右移:左边用0填充,右边丢弃。2.算数右移:左边用原该值的符号位填充,右边丢弃。
关于到底是逻辑右移还是算术右移,取决于编译器的实现,不过大部分位算术右移,如下的VS2022。
先给出一个简单的实例:
给出图解原理(逻辑右移和算术右移):
由上图可得,VS的右移为算术右移,逻辑右移太过于粗暴,不会在乎原来的值是否为正数还是负数 ,只要逻辑右移后计算结果都会为正数。
注:对于一位操作符,不要移位负数,标准未定义。
2.位操作符
位操作符有:& 按位与 | 按位或 ^ 按位异或 ~ 按位取反
注:和以上的移位操作符一样,操作数必须是整数。
&(按位与):两个二进制为1才为1,有一个为0计算结果都是0。
|(按位或):两个二进制中有一个为1,则计算结果为1,两个同时为0才为0。
^(按位异或):两个数相同则为0,不同则为1。
~(按位取反):对一个二进制数进行操作,0变1,1变0。
给出代码展示:
由上图可得,& | ^ ~之间的操作。
通过以上的讲解,我们现在可以开始一些实操了。
3.移位操作符和位操作符之间的操作
实例一:不能创建临时变量(第三变量),实现两个整数的交换。
第一算法:
局限性:如果a和b都非常大,可能导致溢出。
第二算法:
此算法需结合异或的特性,一个数异或另一个数两次,那么等于原本身,同时这个异或操作满足交换律。
实例二:求一个整数在内存中的二进制中1的个数。
算法一:
通过按位与和移位操作对每一位二进制进行判断:在二进制中,只有1&1才会等于1,然后通过移位操作来判断每一位的操作,一个整型在二进制中一共有32位,循环32次。
算法二:
此算法是将一个是数先转化为二进制数之后在进行判断。但是得注意,传入函数的类型得为unsigned int,若为int的话,-1模2,就不会等于1,对于unsigned int 会将-1在内存中存储的11111111111111111111111111111111全部看作有效位,看作为一个正数。即可以解决这个问题。
算法三:
以上通过n&(n-1)的操作,可以每一次使得将n的最右边的1去掉,原理如下:
以上则是有关移位符和位操作符之间的实例操作。