1.基本的位运算符号
&(按位与)
- 运算符两边对应位置都为1时,运算结果位1,否则,只要有一边为false,则结果为false
- 将两边的值作为二进制展开,依次对每一位进行按位与。作用如下
- 11100101 & 01011010 = 01000000
| (按位或)
运算符两边对应位置有一边为1时,运算结果为1。只有两边同时为0时,结果才为0.
- 运算符两边对应位置有一边为1时,运算结果为1。只有两边同时为0时,结果才为0.
- 将两边的值作为二进制展开,一次对每一位进行按位或。作用如下
-
- 11100101 | 01011010 = 11111111
>> (向右移位)
一个操作数进行右移运算的时候,结果就是等于操作数除以2的n次方,n就是右移的位数
<< (向左移位)
一个操作数进行左移运算的时候,实际上就是等于该操作数乘以2的次方,n就是左移的位数
^ (抑或)
只有两边的对应位置的值不一样时,结果为1,否则结果为0。作用如下
00000101 ^ 00000011 = 00000110
~ (取反)
对每一位取反
00000111 取反 11111000
2.运算符的一般技巧
- 位向量:位向量就是用一些二进制位组成的向量。在很多的情况下,我们可以用一个二进制表示一个对象。但是,我们不能直接用一个变量名表示一个位(单独一个位组成的数据类型是不存在的),于是我们可以考虑将多个位组成基本的数据类型,然后通过对这个基本的数据类型进行操作,从而达到对位进行操作的目的。同时,位了方便,把由位组成的基本数据类型组成数组,这样就可以对一定范围的位数据集合进行操作了。
- &运算的规律:由&运算的规则,任何数和0进行 & 都能被置0,任何数和1进行 & 操作都能获得其本身
- | 运算的规律:由 | 运算的规则,任何数和1进行 | 都能被置1,任何数和0进行 | 操作都能获得其本身
- c语言移位运算的规则(此处需要了解反码补码原码的内容,移位使用的补码操作)
- 移位时,移出的位数全部丢弃,移出的空位补入的数与左移还是右移有关。
- 如果是左移,则规定补入的数全部是0;
- 如果是右移,还与被移位的数据是否带符号有关。若是不带符号数,则不补入的数全部为0,若是带符号数,则补入的数全部等于原数的最左端位上的原数(即原符号位)。具体移位规则如下所示
- 例如,设无符号短整型变量a为0111(对应二进制数为0000000001001001),
则:a<<3 结果为01110(对应二进制数为0000001001001000),
a>>4 结果为04 (对应二进制数为0000000000000100),
又如,设短整型变量a为-4(对应二进制数为 1111111111111100),
则:a<<3 结果为-32(对应二进制数为1111111111100000),
a>>4 结果为-1(对应二进制数为1111111111111111)
- 移位时,移出的位数全部丢弃,移出的空位补入的数与左移还是右移有关。
- 移位运算和乘除直接的规律:具有如下几个规则
- m/2^n=m>>n
- m*2^n=m<<n
- m%(2^n)=m&(2^n-1)
5.int 存储过程中制定位置的获取和设置
使用一个大数组,令N=1000000,若数组类型为int,则数组定义为int a[N/32+1](因为一个int占4个字节,一共 是8位,+1实现的进位制度)
显然a[0]可以表示0~31的整数,以此类推,a[i]可以表示32*i~32*(i+1)-1的整数,若a[i]中的第j位为1,则表示 待排序介乎额中存在32*i+j这么一个数,否则不存在。对于待排序集合中的某一个元素b,则有:
i = b / 32;
j = b % 32;
这两句换成位运算可以写成
i = b >> 5;
j = b & 0x1F
如果要将元素对应位置为1,则按以下方式即可:
a[i] = a[i] | (0x1 << j)
6.不同类型存储位向量的问题
char、short、int、long、unsigned char、unsigned short、unsigned int、unsigned long都可以进行移位操作,而double、float、bool、long double则不可以进行移位操作。
位运算和乘法之间的一些实例
a*33=a*32+a*1=a*2^5+a*2^0=a<<5+a<<0;