移位操作符注意:针对补码进行的
在了解移位操作符和位操作符之前,我们需要知道一个十进制的整数是如何在计算机中存储的,以int a = 10 为例,int型占4个字节,一个字节有8位,正数十以二进制存储在这32位中,其在内存中的存储如下,为方便视图中间部分已省略。注意:注意:移位操作都是针对补码进行的,正数的原码、补码、反码相同,负数的原码取反得反码,反码加一得补码。
0 | 0 | 0 | . | . | . | . | . | 0 | 1 | 0 | 1 | 0 |
---|
<<1. 左移操作符
移动正数和负数时一样将这32位向左移动,后面空的位用0代替。例如:a<<1(将a左移一位)得到
0 | 0 | 0 | . | . | . | . | 0 | 1 | 0 | 1 | 0 | 0 |
---|
需要注意的是<<只是操作符,如加减号一样,a的值并没有变,这与a++是不同的。
>>2. 右移操作符
移动正数时,前面的补0,移动负数时,前面补1,注意:一个负数一直右移,最终得到-1。
1 | 1 | 1 | . | . | . | . | 1 | 1 | 1 | 1 | 1 | 1 |
---|
位操作符注意:针对补码进行的
针对位操作符,他们的操作数必须是整数
1.&按位与
每一位上,同为1时为1,否则为0。以 a = 3 & 5 为例,a的二进制为001。
3 | : | 0 | 0 | 0 | . | . | . | 0 | 0 | 0 | 1 | 1 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
5 | : | 0 | 0 | 0 | . | . | . | 0 | 0 | 1 | 0 | 1 |
a | : | 0 | 0 | 0 | . | . | . | 0 | 0 | 0 | 0 | 1 |
上面给的是两个正数的按位与,下面给两个负数的按位与,char a = -2;char b= -5,char c = a&b ;c=?
首先写出,a,b的补码。:
a:1111 1110(补)
b:1111 1011(补)
a&b=1111 1010(补)转化为原码为 1000 0110(原)
故c= -6.注意:任意一个数和-1按位与,得其本身。
2.按位或
每一位上,有1为1,同0为0。以 a = 3 | 5 为例,a的二进制为111。
3 | : | 0 | 0 | 0 | . | . | . | 0 | 0 | 0 | 1 | 1 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
5 | : | 0 | 0 | 0 | . | . | . | 0 | 0 | 1 | 0 | 1 |
a | : | 0 | 0 | 0 | . | . | . | 0 | 0 | 1 | 1 | 1 |
注意:自己和自己按位或,得其本身。
3.^按位异或
每一位上,相同为0,不同为1。以 a = 3 | 5 为例,a的二进制为110。
3 | : | 0 | 0 | 0 | . | . | . | 0 | 0 | 0 | 1 | 1 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
5 | : | 0 | 0 | 0 | . | . | . | 0 | 0 | 1 | 0 | 1 |
a | : | 0 | 0 | 0 | . | . | . | 0 | 0 | 1 | 1 | 0 |
注意:自己和自己按位异或为0。
~ 对一个数的二进制按位取反
对一个数的二进制按位取反,~5对应的二进制如下
5 | : | 0 | 0 | 0 | . | . | . | 0 | 0 | 1 | 0 | 1 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
a | : | 1 | 1 | 1 | . | . | . | 1 | 1 | 0 | 1 | 0 |
通过移位操作符和位操作符可以比较容易的实现某些功能,例如:统计一个二进制数中1的个数。
方法一
对于一个十进制数,想要得到它每一位上的数,可以通过反复%10,/10来实现,对于一个二进制数,可以通过%2,/2来实现。缺陷:不能计算负数。
int Mo(int n)//通过模
{
int count = 0;
while (n)
{
int b = 0;
b = n % 2;
if (b == 1)
count++;
n /= 2;
}
return count;
}
方法二
采用按位与,对任意整数n,n&1,可以判断最后一位是否为1,判断完后n>>1,即可判断下一位,依次。
int Wei(int n)//按位与
{
int count = 0;
while (n)
{
if (n & 1 == 1)
count++;
n = n >> 1;
}
return count;
}