计算机基础——JAVA位操作

前言:我们之前讲过原码反码和补码的关系和相应的转换操作。在JAVA中,采用的也是补码的形式进行数据的操作,这一点需要注意。下面是JAVA中提供的常用的bit位操作符:

1、~操作符(取反),对二进制位进行取反的操作,0变成1,1变成0。例如,~(-3)之后的值是 2,[-3]补码 = 11111101,取反后 = 00000010 = [2]补码 = 2 。

2、&操作符(与),对二进制位进行与的操作,同时为1的时候为1,其他情况为0。例如,(-3)&46的值为 44,[-3]补码 = 11111101,[46]补码 = 00101110,进行与操作后,同时为1的时候为1,其他情况为0 ,得到二进制补码 = 00101100 = 44 。

3、|操作符(或),对二进制位进行或操作,只要有一个为1的时候结果为1,同时为0才会为0。例如,(-3)| 46的值为-1,[-3]补码 = 11111101,[46]补码 = 00101110,进行或操作,得到二进制补码 = [11111111]补码 =[10000001]原码 = -1。

4、^操作符(异或),对二进制进行异或操作,对应位的值相同为0,不同为1。例如,(-3)^ 46的值为-45,[-3]补码 = 11111101,[46]补码 = 00101110,进行异或操作,得到二进制补码 = [11010011]补码 = [11010010]反码 = [10101101]原码 = -45。

5、<<操作符(左移),二进制位向左移动,右边补0。(-3)<<2的结果为-12;(-3)<<7的结果为-128,[-3]补码 = [11111101],左移七位之后变成[10000000]补码 = -128。

6、>>操作符(右移),二进制位向右移动,当为负数时左边补1,正数时左边补0。(-3)>>2的结果是-1,[-3]补码= [11111101]补码>>2 = [11111111]补码 = [10000001]原码 = -1;46 >> 2 结果是 11。

下面我们针对于一些特定的需求进行位操作:
应用场景一:有一个byte字节是从底层C语言通过JNI传递到应用层来,这个byte包含的是一个车辆速度值的信息,按照规定车速值肯定不会为负数,同时车速值的范围在0~255之间。由于C语言处理这个字节的时候是按照无符号来处理的,所以它认为一个字节8位可以搞定这个数据,然后就把速度值通过这个字节传递上来了。
然后我也把这个字节接收过来直接拿来显示,结果懵逼了,居然出现了负数。原因就在于,当速度值超过127之后,最高位就为1了,而JAVA默认是带符号位操作的,结果本来是205的速度值,二进制为[11001101]原码 = [10110011]补码 ,然后我们取出来的时候用的就是补码的值,因此就显示为了-51。
因此我们需要使用一些位的操作来把这个值取出来。最简单的方式就是用一个int来装这个byte数据,byte b,int i ,不能直接用i = b;这样的方式来赋值,因为这样符号位还是1负数,可以这样操作:i = b & 0XFF;

应用场景二:把int i 值转换成byte[] datas数组,要求后面可以通过该byte数组恢复int值;代码可以如下:

int i = -45782258;
        byte[] datas = new byte[4];
        datas[0] = (byte)(i&0x000000ff);
        datas[1] = (byte)((i&0x0000ff00)>>8);
        datas[2] = (byte)((i&0x00ff0000)>>16);
        datas[3] = (byte)((i&0xff000000)>>24);
        int j = (int)(datas[0]&0xFF | (datas[1]<<8)&0XFF00 | (datas[2]<<16)&0XFF0000 | (datas[3]<<24)&0XFF000000);
        System.out.println(j);
-------------------
打印结果:-45782258

猜你喜欢

转载自blog.csdn.net/yus201120/article/details/76020385