回覆列表
  • 1 # Kwanlinli

    位運算在驅動開發中是經常遇到的,尤其是置0和置1。既要指定的位數發生變化,又不能改變其它位的值,還要高效率的編寫程式碼,這時候技巧就很重要了。在位運算中有幾個符號: | 按位或 、& 按位與 、 ^ 異或 、~按位非。

    應用技巧

    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<

    4

    將int型變數a的第k位置1

    a=a|(1<

    5

    int型變數迴圈左移k次

    (設sizeof(int)=16)

    a=a<>16-k

    6

    int型變數a迴圈右移k次

    (設sizeof(int)=16)

    a=a>>k|a<<16-k

    #include <stdio.h>

    int main()

    {

    printf("學習從來不是一個人的事情,要有個相互監督的夥伴\n");

    printf("工作需要學習C/C++或者有興趣學習C/C++的夥伴可以家我球球

    _2208165112\n");

    return 0;

    }

    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

    boolean power2(int x)

    {

    return ((x&(x-1))==0)&&(x!=0);

    }

    9

    用位運算子交換兩個整數

    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

    判斷賦值

    if (x == a) x= b;

       else x= a; 等價於 x= a ^ b ^ x;

    15

    x 的 相反數

    (~x+1)

    技巧雖好,但是大家還是最好自己啃一啃才能知道味道呀,閒暇時,不防拿出來品一品,悟一悟其中的原理所在。

    練一練

    #include

    int main()

    {

    unsigned int i = 0x9f43bda5;

    unsigned int ret = 0;

    printf("i %x\n",i);

    //將 i 第3位置1

    ret = i | ( 1 << 3 );

    printf("ret %x\n",ret);

    //將 i 第2位置0

    ret = i & ~( 1 << 2 );

    printf("ret %x\n",ret);

    //將 i 第4~9位置1

    ret = i | ( 0x3f << 4 );

    printf("ret %x\n",ret);

    //將 i 第3~7位置0

    ret = i & ~(0x1f << 3 );

    printf("ret %x\n",ret);

    //將 i 第1~7和9~11位置1

    ret = i | ( 0x3f << 1 | 7 << 9);

    printf("ret %x\n",ret);

    //將 i 第2~8位置13~20位置0

    ret = i & ~( 0x7f << 2 | 0xff << 13 );

    printf("ret %x\n",ret);

    }

  • 中秋節和大豐收的關聯?
  • 86拍整小節休止用全休止符嗎?