巧用 C 语言的位运算

时间:2022-01-26 00:42:13

在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)