在了解移位操作符和位操作符之前,我们需要知道一个十进制的整数是如何在计算机中存储的,以int a = 10 为例,int型占4个字节,一个字节有8位,正数十以二进制存储在这32位中,其在内存中的存储如下,为方便视图中间部分已省略。注意:注意:移位操作都是针对补码进行的,正数的原码、补码、反码相同,负数的原码取反得反码,反码加一得补码。
000.....01010移动正数和负数时一样将这32位向左移动,后面空的位用0代替。例如:a<<1(将a左移一位)得到
000....010100需要注意的是<<只是操作符,如加减号一样,a的值并没有变,这与a++是不同的。
移动正数时,前面的补0,移动负数时,前面补1,注意:一个负数一直右移,最终得到-1。
111....111111针对位操作符,他们的操作数必须是整数
每一位上,同为1时为1,否则为0。以 a = 3 & 5 为例,a的二进制为001。
3:000...000115:000...00101a:000...00001上面给的是两个正数的按位与,下面给两个负数的按位与,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按位与,得其本身。
每一位上,有1为1,同0为0。以 a = 3 | 5 为例,a的二进制为111。
3:000...000115:000...00101a:000...00111注意:自己和自己按位或,得其本身。
每一位上,相同为0,不同为1。以 a = 3 | 5 为例,a的二进制为110。
3:000...000115:000...00101a:000...00110注意:自己和自己按位异或为0。
对一个数的二进制按位取反,~5对应的二进制如下
5:000...00101a:111...11010通过移位操作符和位操作符可以比较容易的实现某些功能,例如:统计一个二进制数中1的个数。
方法一 对于一个十进制数,想要得到它每一位上的数,可以通过反复,/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; }