我们经常会看到这样的语法

(byte) 0xAD

 

0xAD实际是个16进制,转换成二进制为:10101101,转换成10进制是:173,它是个正数

10101101只是int的简写,int由4个byte字节,即32位bit组成,实际的值是

(00000000 00000000 00000000 )10101101

 

int由4 byte组成,因此int转byte是会掉位的,直接截取最后一个字节,即:

10101101

符号位是1,因此它是负数,负数的存储方式是补码。因此要先求出补码才能计算值。

求补码方式为:

符号位不变,其他位取反,然后+1,映射到这里则为

11010010 + 1 -> 11010011

则值为 -(2^6+2^4+2^1+2^0) = -83

  

因此0xAD = 173 ,(byte) 0xAD=-83

 

有时候,我们会有一种特殊的需求,比如用bit位上的0或者1表明某一个值是否存在,如

0000 0101 可以表示第0位 -> 1 -> 存在

                                 第1位 -> 0 -> 不存在

                                 第2位 -> 1 -> 存在

                                 ……

这样,一个byte就能表示8个位置是否有值,可用于8个不同类型的值是否存在,或者用于排序数字

这样做的好处是利用一个byte有8bit的特点标识8种情况,大量节省了空间,并且当一个byte转换成二进制时,可以立即清楚某一位是否存在,从这个意义上来说,他比你声明8个byte更清晰,而且标识的范围更广,因为他还可以处理同时存在的逻辑。

当然,有利就有弊,如果想用于数据库按标识查询,则需要人为来处理多种情况,这甚至是及其复杂的,诸如存在mysql某一列,又需要按字段进行条件匹配时,不推荐此方式

当获取到byte,判断某一位bit是否为1的方式

    /**
     * 比如3的二进制是 0000 0011
     * isBitV1(3,0) 是1 true
     * isBitV1(3,1) 是1 true
     * isBitV1(3,2) 是0 false
     * 判断byte的某一位上是否有值
     *
     * 0x1其实就是1,1的二进制是0000 0001
     * @param b
     * @param position 第几位
     * @return
     */
    private boolean isBitV1(byte b, int position) {
        if (position == 0) {
            return (b & 0x1) > 0;
        } else {
            return (b >> position & 0x1) > 0;
        }
    }

0x1是16进制,表示1,之所以很多源码里面喜欢用0x1,而不是1,我推测是这样少了一次int转2进制或16进制的转换,效率更高

posted on 2017-02-08 10:09  j.liu windliu  阅读(26620)  评论(0编辑  收藏  举报