在C语言编程中,我们常常能用到一些位运算来代替常规的一些运算。因为在多数情况下位运算的效率会高于普通的运算。例如用右移一位带代替除以2。下面介绍一些常用的位运算技巧。
位运算是指按二进制进行的运算。在系统软件中,常常需要处理二进制位的问题。C语言提供了6个位操作运算符。这些运算符只能用于整型操作数,即只能用于带符号或无符号的char,short,int与long类型。
C语言提供的位运算符列表:运算符 含义 描述
& 按位与 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0
| 按位或 两个相应的二进制位中只要有一个为1,该位的结果值为1
^ 按位异或 若参加运算的两个二进制位值相同则为0,否则为1
~ 取反 ~是一元运算符,用来对一个二进制数按位取反,即将0变1,将1变0
<< 左移 用来将一个数的各二进制位全部左移N位,右补0
>> 右移 将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补0
位运算应用口诀
清零取反要用与,某位置一可用或
若要取反和交换,轻轻松松用异或
应用举例
1,判断int型变量a是奇数还是偶数
a&1 = 0 偶数
a&1 = 1 奇数
2, 取int型变量a的第k位 (k=0,1,2……sizeof(int)),即a>>k&1
3, 将int型变量a的第k位清0,即a=a&~(1 < <k)
4, 将int型变量a的第k位置1, 即a=a|(1 < <k)
5, int型变量循环左移k次,即a=a < <k|a>>16-k (设sizeof(int)=16)
6, int型变量a循环右移k次,即a=a>>k|a < <16-k (设sizeof(int)=16)
7,整数的平均值
对于两个整数x,y,如果用 (x+y)/2 求平均值,会产生溢出,因为 x+y 可能会大于INT_MAX,但是我们知道它们的平均值是肯定不会溢出的,我们用如下算法:
int average(int x, int y) //返回X,Y 的平均值
{
return (x&y)+((x^y)>>1);
}
8,判断一个整数是不是2的幂,对于一个数 x >= 0,判断他是不是2的幂
boolean power2(int x)
{
return ((x&(x-1))==0)&&(x!=0);
}
9,不用temp交换两个整数
void swap(int x , int y)
{
x ^= y;
y ^= x;
x ^= y;
}
10,计算绝对值
int abs( int x )
{
int y ;
y = x >> 31 ;
return (x^y)-y ; //or: (x+y)^y
}
11,取模运算转化成位运算 (在不产生溢出的情况下)
a % (2^n) 等价于 a & (2^n - 1)
12,乘法运算转化成位运算 (在不产生溢出的情况下)
a * (2^n) 等价于 a < < n
13,除法运算转化成位运算 (在不产生溢出的情况下)
a / (2^n) 等价于 a>> n
例: 12/8 == 12>>3
14, a % 2 等价于 a & 1
15, if (x == a)
x= b;
else
x= a;
等价于 x= a ^ b ^ x;
16,x 的 相反数 表示为 (~x+1)