• 《C语言笔记:位操作相关》


    一,位操作一般用法

      1,特定位清零用“&”。

        要想把一个数的特定位清零,就需要构造另一个数,这个数的对应特定位为0,其他位为1。2

      2,特定位置1用“|”。

        要想把一个数的特定位置1(设置特定位),就需要构造另一个数,这个数的对应特定位为1,其他位为0。

      3,特定位取反用“^”。

        要想把一个数的特定位取反,就需要构造另一个数,这个数的对应特定位为1,其他位为0。

    二,如何构造“另一个数”。

      1,如果这个数比较少位为“1”,大部分为“0”,则可以通过连续多“1”左移n位得到。

      2,如果这个数比较少位为“0”,大部分为“1”,则可以先通过构建其位反数,然后再位取反来得到。

      3,如果想要构造的数中连续1(连续0)的部分不止一个,那么可以通过多段分别构造,然后再彼此位或即可。

    三,位运算实战。

      1,给定一个整数型a,设置a的bit3,同时保证其他位不变。

        a |= (0x1<<3);

      2,给定一个整数型a,设置a的bit3~bit7,同时保证其他位不变。

        a |= (0x1f<<3);

      3,给定一个整数型a,清除a的bit15,同时保证其他位不变。

        a &= (~(0x1<<15));

      4,给定一个整数型a,清除a的bit15~bit23,同时保证其他位不变。

        a &= (~(0x1ff<<15));

      5,给出一个整数型a,取出bit3~bit8。

        第一步:先把bit3~bit8保持不变,其他位清零。

            a &= ((0x3f<<3)) ;

        第二步:再将其右移3位得到结果。

            a>>3;

      6,给一个寄存器的bit7~bit17赋值937(其他位不受影响)。

        关键点:第一,不能影响其他位,第二,并不知道bit7-bit17中原来的值。

        第一步:对于关键点二,得先把bit7~bit17清零。

          a &= (~(0x7ff<<7));

        第二步:将937写到对应位。

          a |= (937<<7);

      7,将一个寄存器的bit7~bit17的值加17(其他位不受影响)。

        第一步:先读出对应位的数。

          data = (a & (0x7ff<<7))>>7;

        第二步:data  += 17;

        第三步:对应位清零。

          a &= (~(0x7ff<<7));

        第四步: a |= (data<<7);

      8,给一个寄存器的bit7~bit17赋值937,给一个寄存器的bit21~bit25赋值17(其他位不受影响)。

        两次第6题。

        a &= (~(0x7ff<<7) | ~(0x1f<<21));

        a |= ((937<<7) | (17<<21))

      9,宏实现置位,复位。(一般笔试题中规定的是最右边为第一位)

        #define SET_BIT(x,n)  (x|((1U)<<(n-1)))

        #define CLEAR_BIT(x,n) ((x & ~((1U)<<(n-1))))

      10,截取变量的部分连续位。比如变量0x88,即0x10001000b,若截取第2~4位,则值为100b = 4。

        #define GETBITS(x,n,m) ((x & ~(~(0U)<<(m-n+1))<<(n-1))>>(n-1))

        分析:

          #define GETBITS(x,n,m)   ((x    &    ~(~(0U)<<(m-n+1))   <<(n-1))   >>(n-1))

          

          第一次分解:

            (x & ~(~(0U)<<(m-n+1)) <<(n-1))                    >>         (n-1))

          第二次分解:

            x                              &                                        ~(~(0U)<<(m-n+1)) <<(n-1)

          第三次分解:

             ~(~(0U)<<(m-n+1))                                        <<         (n-1)

           ~(~(0U)<<(m-n+1)):得到连续(m-n+1)个1的数 。

          ~(~(0U)<<(m-n+1)) << (n-1):将连续(m-n+1)个1的数 移动到对应连续位处。

          (x & ~(~(0U)<<(m-n+1)) <<(n-1)):取出对应位处的位值。

          (x & ~(~(0U)<<(m-n+1)) <<(n-1)) >> (n-1)):得到所求连续位的值。

      

    #include <stdio.h>
    
    #define GETBITS(x,n,m)    ((x&(~(~(0u)<<(m-n+1))<<(n-1)))>>(n-1))
    #define CLEARBITS(x,n,m)   (x&(~((~(~(0u)<<(m-n+1)))<<(n-1))))
    #define SETBITS(x,n,m)    (x|(~(~(0u)<<(m-n+1)))<<(n-1))
    
    int main()
    {
        int a = 0x88;
    
        printf("  %d  
    ",GETBITS(a,2,4));    //4
    
        a = 0xff;
        
        printf(" 0x%x  
     ",CLEARBITS(a,2,4));  // 0xf1
    
        a = 0xf1;
        
        printf(" 0x%x  
    ",SETBITS(a,2,4));     //0xff
    }
  • 相关阅读:
    同时使用gitee和github
    vim的四种模式及模式切换
    Vim使用入门
    Vim, Vim Diff, Vim Easy, Vim Read-only 区别
    公钥与私钥
    Linux使用Aria2命令下载BT种子/磁力/直链文件
    Content-Type /AJAX /@ResponseBody
    IDEA 添加serialVersionUID 检查
    Servlet中的Context Path | Servlet Path | Path Info
    第K大的数
  • 原文地址:https://www.cnblogs.com/xuxianshen/p/13912690.html
Copyright © 2020-2023  润新知