最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 位运算初探

    正文概述 掘金(小丶k)   2021-05-29   45

    位运算初探

    位运算基础

    位操作定义
    与(&)操作只有左右两边都为 1 的时候,其结果为 1。
    可以看作是取位操作,例如:x & (1 << n) 就是 取出整数 x 的第 n 位
    或(|)操作只要左右两边有一个为 1,结果就是 1。
    可以看作是赋值操作,例如:x | (1 << n) 就是将 x 的第 n 位赋值为 1
    取反(~)操作对一个整数按位取反,1 变成 0,0 变成 1。
    在有符号整数上,使用取反操作需要小心,因为有符号整数存储中最高是符号位
    异或(^)操作左右两边一样则为 0,不一样则为 1。左移(<<)和右移(>>)左移是所有位向左移,向后补 0,左移 n 位相当于乘以 2 ^ n
    右移是所有位向右移,弃掉低位,相当于除以 2 ^ n

    与(&)操作

    这里左右是指数字转换成 二进制后的左右, 例如 3 & 5

    3 & 5
      011 // 3 的二进制 
    
    & 101 // 5 的二进制
    
      001 // 结果为 1
    

    如果参加 & 运算的是附属(如 -3 & -5),则要以补码形式表示为二进制数,然后再按位进行“与”运算

    补码就是取反然后加 1

    6   二进制    110
        取反   ...001
        加1    ...002
        二进制2要进位 ...010 
    

    位运算初探

    • 清零 将二进制数 11100101 的第二位清零 这里的第二位我们是右至左,右边第一个数是 0 位,类似于数组索引
          1110 0101
      &   1111 1011
      -------------
          1110 0001
      
    • 取一个数的某些指定位
          1111 1010 取后四位
      &   0000 1111
      -------------
          0000 1010
      

    或(|)操作

        0011 0000
    |   0000 1111
    -------------
        0011 1111
    
    • 使用位运算将小写字母转换成大写字母,大写字母转小写字母
    字母ASII二进制
    A650100 0001a970110 0001B660100 0010b980110 0010Z900101 1010z1220111 1010
    • 小写字母转大写字母

      首先我们可以看出大写字母和小写字母 低四位相同,只要第 5 位为 1 就是大写字母,我们考虑 或(|)操作,根据或(|)操作的特性那我们要找的那个数的低四位应该都是 0。

      我们再看高四位

        高四位
      A 0100
      a 0110
      

      到这我们可以看出,或(|)操作,当位为 1 时此位是无法更改的,所以或(|)操作不可取。

      与(&)操作依旧低四位相同,根据与(&)操作的特性那我们要找的那个数的低四位应该都是 1

        高四位
      A 0100
      a 0110
      ------
        010?
        
      Z 0101
      z 0111
      ------
        0101
      

      由此我们得出我们要找那个数二进制就是 0101 1111,十进制 95

    位运算初探

    // C语言
    printf("%c", 'z' & 95);
    // js 
    // 'a'.toLocaleUpperCase(); // 字符转大写方法...
    String.fromCharCode(("a".charCodeAt() & 95)); // 好麻烦... 
    
    • 大写字母转小写字母
    // C语言
    printf("%c", 'Z' | 32);
    // js
    String.fromCharCode(("A".charCodeAt() | 32));  
    

    异或(^)操作

        0011 1001
    ^   0010 1010
    -------------
        0001 0011
    
    • 使特定位反转

    设有 0111 1010, 想使其低四位反转,即 1 变 0, 0 变为 1。

        0111 1010
    ^   0000 1111
    -------------
        0111 0101
    
    • 交换两个值,不用临时变量
    a ^= b;
    b ^= a;
    a ^= b;
    
    a = 1 二进制 0001
    b = 2 二进制 0010
    
    a ^= b;
      0001
    ^ 0010
    ------
      0011
      
    b ^= a;
      0011
    ^ 0010
    ------
      0001
      
    a ^= b;
      0011
    ^ 0001
    ------
      0010
    

    左移(<<)和右移(>>)

    位运算初探

    • x & (1 << n) 就是 取出整数 x 的第 n 位,如果结果大于 0,则该位为 1,反之则为 0

    • x | (1 << n) 就是将 x 的第 n 位赋值为 1,

    5 | 1 = 7
    5 | (1 << 1) = 7
        0101
    |   0010
    --------
        0111
    

    计算两正整数之和

    • 不使用 + 、 -
        0001
    +   0101
    --------
        0110
    
    • 取出两个数字的相同位,如果都为 1 进位,单个为 1 赋值为 1,否则为 0

    • 取位

    let bitA = a & flag;
    let bitB = a & flag;
    
    • 赋值
    let carry = false;// 是否进位
    if (bitA && bitB) { // 都为 1
         // 进位
         if (carry) { // 低位已进位(此位 3 个 1)赋值
            let sum |= flag;
         }
         carry = true;
    } else if (bitA || bitB) { // 单个为 1
        if (!carry) { // 低位未进位赋值
           // 赋值
           let sum |= flag;
        }
        // 如果低位已进位(此位 2 个 1)进位
    } else { // 都为 0
        if (carry) { // 低位已进位赋值
            let sum |= flag;
            carry = false;
        }
    }
    
    const getSum = function (a, b) {
        let sum = 0;
        let flag = 1;
        let carry = false;
        while (flag <= a || flag <= b) {
            let bitA = a & flag;
            let bitB = b & flag;
            if (bitA && bitB) {
              if (carry) {
                sum |= flag;
              }
              carry = true;
            } else if (bitA || bitB) {
              if (carry) {
                carry = true;
              } else {
                sum |= flag;
              }
            } else {
              if (carry) {
                sum |= flag;
              }
              carry = false;
            }
            flag <<= 1;
        }
        if (carry) {
            sum |= flag;
        }
        return sum;
    };
    

    起源地 » 位运算初探

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元