位运算中的小技巧

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/q__y__L/article/details/53941450

以前在我看来,位运算是一个可有可无的东西,但是随着经验的积累,发现位运算有时候能有效的解决特定的问题,以及提高程序的效率,所以下面有几个比较实用的技巧供大家参考。

  1. 结构体中实现位段
    c语言结构体可以实现位段,它的定义形式是在一个定义的结构体成员后面加上冒号,然后是该成员所占用的位数。位段结构体成员必须是int或者unsigned int类型,位段在内存中的存储方式是由具体的编译器决定的。
    如下:
typedef struct 
{
    int aa:3 ;
}Test;

我们限定了成员变量aa为3位,因为是有符号类型,所以除去符号位,aa只能表示0-3的范围。当aa被复制为4的时候回这么样呢?
这里写图片描述
我们简单分析一下,首先t.aa=4,赋值后二进制aa=0100(B),由于aa只有3位,所以保留下来的是100(B),而首位是代表符号位的,也就是说系统认为这是一个负数,其绝对值为先减一为011,再取反码为100(B)=4(d),所以结果为-4.若将aa声明为unsigned int 则结果可以正确显示出4,但是超过7也会出问题。


2.加快某些计算
将某个数乘以2,可以利用位运算,cpu直接支持位运算,效率比乘法高,x*8可以用x<<3,同样x*7可以用(x<<3)-X来表示。


  1. 求平均值
    (x+y)/2用位操作可以写为(x&y)+((x^y)>>1).第一部分是取x和y都有1的位,第二部分是取x,y不同的时候的部分,相加再除以2,所以最后是2个数的平均值。

  1. 求整数中二进制表示中1的个数
    核心代码如下:
int fun(int x)
{
    int count_x=0;
    while(x)
    {
        count_x++;
        x=x&(x-1);//核心语句
    }
    return n;
}

大家可以自己敲一下,看看是如何操作的。大致如下,如果x是一个奇数,进过一次操作后,减一,即左右边的位变为0,得到一个偶数,如果x是一个偶数,则每次循环后,x最靠右边的1变为0,即每次操作后,x二进制中的1都会少一个。如下图的例子。
这里写图片描述


以后可能会继续补充……

猜你喜欢

转载自blog.csdn.net/q__y__L/article/details/53941450