zoukankan      html  css  js  c++  java
  • b&0xF 与 b是什么关系

    转载自: https://blog.csdn.net/u013513053/article/details/104674801/

    今天同事看到一行代码

    if ((d2[i] & 0x0F) == 0x0F || (d2[i] & 0xF0) == 0xF0){
    //省略
    }
    

    然后就很奇怪这个运算,一个数值与上 0x0F,判断是否等于0x0F。那么这个数值与 0xF不就是数字本身么?为啥要多此一举呢?
    我试验了一下,的确

    1 & 0x0F = 1
    10 & 0x0F = 10
    15 & 0x0F = 15

    这么看的确是很困惑,如果这样的话,为啥不直接判断 d2[i] == 0x0F 这样呢?

    负数操作

    我印象中好像我也这么干过,但是太久远了一直想不起来为啥。我就去查资料。但是百度出来的也没说出所以然,我忽然想了起来,负数与之后也是这样么?

    我用-1做实验,果然结果是不一样的。
    -1 & 0x0F = 15
    -10 & 0x0F = 6
    -15 & 0x0F = 1

    这是为什么呢?
    java中的几个规则:

    1. Java中byte的大小是8bits,int的大小是32bits,byte的范围是[-128,127],int的范围是[-231,231-1]。

    2. Java中数值的二进制是采用补码的形式表示的。

    byte 的长度是有限的,最大是127,那么对于十六进制的FF怎么办呢?我们经常要存储十六进制的数字,而十六进制一位最大值FF 就是255,byte肯定超限了。java也是很贴心的给出了解决,0-127直接表示就可以,128也就是 0x80,就用负数表示,值为-128。值从负值递增,129就是-127,130就是-126依次类推。,-1 到最大 255,也就是0xFF。

    那么从byte中取出来16进制数怎么办,那就用byte 值与上 0xFF。注意这里是0xFF。

    这样就可以理解了,-1其实不是-1,而是十六进制0xFF。所以用-1&0x0F的结果就相当于 0xFF&0x0F。

    然而结束了么?并没有

    & 操作

    上面例子测试只到了15,我们继续把数值调大试一下
    16 & 0x0F = 0
    17 & 0x0F = 1

    这里又得说一下 & 操作符的意思。很简单,就一句话

    全部为1则为1,有一位0则为0

    这里是二进制的位,每一位进行比较操作,全部为1则为1,有一个为0则为0。这么说可能不太明白,举个例子就好了

    8 & 1

    转换为二进制(二进制转换就不多说了)
    1000&1

    补位,不足的前面补0。这里1前面需要补足
    1000&0001

    计算,全部为1的为 1 ,有0的为 0
    每一位分别是
    1&0 = 0
    0&0 = 0
    0&0 = 0
    0&1 = 0
    最终为
    0000
    结果为 0

    这是原理,但是相信解释原理即使明白了,实际运用也是困难的。谁闲着没事转二进制计算?数字小还可以,要是数字大呢?算去吧

    这里我们找找有没有简便的方法或者规律,我们不妨多些几个看看

    1&1 = 1
    2&1 = 0
    3&1 = 1
    4&1 = 0

    2&2 = 2
    3&2 = 2
    4&2 = 0
    5&2 = 0
    6&2 = 2
    7&2 = 2
    8&2 = 0
    9&2 = 0

    3&3 = 3
    4&3 = 0
    5&3 = 1
    6&3 = 2
    7&3 = 3
    8&3 = 0
    9&3 = 1
    10&3 = 2

    我们可以发现一些结论

      1. 一个数&自身等于这个数自身
      2. 奇数&1等于1,偶数&1 =0。我们可以利用这个来判断奇偶(运算速度比取余快)
      3. 清零。如果想将一个单元清零,即使其全部二进制位为0,只要与一个各位都为零的数值相与,结果为零。
      4. 取一个数中指定位
        方法:找一个数,对应X要取的位,该数的对应位为1,其余位为零,此数与X进行“与运算”可以得到X中的指定位。
        例:设X=10101110,
        取X的第4位,用 X & 0000 1111 = 0000 1110即可得到;
        还可用来取X的2、4、6位。
  • 相关阅读:
    庆祝一下开通了第一条博客!
    查看树莓派温度
    Ubuntu Server for Raspberry Pi部署Jenkins
    acme.sh部署RSA、ECC双证书(使用阿里云API)
    Ubuntu Server 20.04换用阿里源
    ESP32使用NTP同步时间
    C语言的可变参数函数
    一种Θ(1)的计算32位整数二进制中1的个数的方法
    CentOS 8安装Docker
    CentOS 8搭建LNMP + WordPress(三)
  • 原文地址:https://www.cnblogs.com/kate7/p/14144668.html
Copyright © 2011-2022 走看看