byte型&十六进制

来源:互联网 发布:高清混合矩阵排名 编辑:程序博客网 时间:2024/06/02 02:43
先po出一段代码
if (((int)scanData[startByte+2] & 0xff) == 0x02 &&((int)scanData[startByte+3] & 0xff) == 0x15) {   patternFound = true;   break;   }

看到if判断中的“&”,我首先是好奇它在此处是逻辑运算符还是位运算符。(这是不是一个比较傻的想法?)

后来发现,“&”在此处做逻辑运算符没什么意义,但是它作为位运算符,在这为什么要这样用?

首先来看“&”作为位运算符的用法:

       &(按位与)主要是两个二进制操作数进行按位与操作时,两位都是1结果才是1,即如果是1&1得到的结果才是1,其他情况都是0。

于是我又有一个奇怪(蠢)的想法:&是只能被二进制数操作吗?那在此处左右两边都不是二进制,是怎么回事?在被人鄙视过之后,才明白&只是操作数的二进制形式,操作数可以是二、八、十、十六进制。

于是第三个问题:0xff的十进制是255,八位二进制就是11111111,一个数&上它,应该是不变的。

网上查原因,发现了一个例子:

public class Test {    public static void main(String[] args) {        byte[] a = new byte[10];        a[0]= -127;        System.out.println(a[0]);        int c = a[0]&0xff;        System.out.println(c);    }}

输出结果是-127和129。

原来&上0xff是会不一样的。

还是那篇文章,给出了原因,计算机存储。

计算机内的存储都是利用二进制的补码进行的。对于正数原码来说,补码和反码都是其本身,首位表示符号位。对于负数,情况稍微复杂,反码是对原码除符号位之外作取反运算,补码是对反码作+1运算。

byte类型的-127,其计算机存储的补码是10000001(8位),将其作为int类型向控制台输出的时候,jvm作了一个补位的处理,因为int类型是32位,所以补位后的补码就是1111111111111111111111111 10000001(32位),这个32位二进制补码表示的也是-127.虽然byte->int(八位扩展到32位),计算机背后存储的二进制补码由10000001(8位)转化成了1111111111111111111111111 10000001(32位)很显然这两个补码表示的十进制数字依然是相同的。

但是我们更关注的往往是计算机的存储内容,所以二进制补码更为重要。所以&上0xff也是为了保持二进制补码的一致性。当低位byte向高位int转化时,高位自动补1,这会导致二进制补码的不一致(尽管转化为十进制后,他们的十进制数还是一样)。为了保证二进制补码的一致性,&上0xff,如-127(byte型)&0xff,计算过程为:

 -127&0xff=1111111111111111111111111 10000001&11111111=000000000000000000000000 10000001=129(十进制),尽管十进制数不同了,但保持了二进制补码的一致。

byte型的-127之所以会先扩充到32位,是因为当系统检测到byte可能会转化为int型时,会自动将byte的内存空间高位补1(也就是按符号位补位),然后再参与运算。

原创粉丝点击