Java位运算知识点整理

 

最近因为工作的原因,需要使用到一些位运算相关的知识点,所以重新回顾和整理了一下。

位操作基础

符号描述运算规则
& 与运算 两个位都是1时,结果才为1
| 或运算 两个位都是0时,结果才为0
^ 异或 两个位相同时为0,不同时为1
~ 取反 0变1,1变0
<< 左移 各二进制全部左移若干位,高位丢弃
>> 右移 各二进制全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移)
Java中左边空出的位用0或者1填,正数用0负数用1填,低位右移溢出则舍弃该位。

注意以下几点:

  1. 在这6种操作符,只有~取反是单目操作符,其它5种都是双目操作符。
  2. 位操作只能用于整形数据,对float和double类型进行位操作会被编译器报错。
  3. 位操作符的运算优先级比较低,因为尽量使用括号来确保运算顺序,否则很可能会得到莫明其妙的结果。比如要得到像1,3,5,9这些2^i+1的数字。写成int a = 1 « i + 1;是不对的,程序会先执行i + 1,再执行左移操作。应该写成int a = (1 « i) + 1;
  4. 另外位操作还有一些复合操作符,如&=、|=、 ^=、«=、»=。

看下常用的左移和右移操作

比如针对「01001000」进行移位操作 左移2位 => 00100000 右移2位 => 00010010

10进制、2进制、16进制之间的转换

2进制和10进制间的转换

10进制到2进制的转换,我们可以通过2进制的每移动一个高位都是2的n次方来分析,从低到高分别是0,2,4,8,16,32…… 这个时候当出现一个10进制的值时,可以优先查找它的最大2的n次方的值,比如35,可以拆解为32+2+1,那对应到2进制的表示就是 100011。下面用表格来表达会更清楚。 用下面的表格表示一个8位的2进制(用8位是因为byte是8位)

二进制00000000
十进制 128 64 32 16 8 4 2 0

2进制和16进制互转

16进制的字符集是 「0123456789ABCDEF」,分别代表着从0到15的数字 一个16进制的值需要4位2进制来表示,因为F也就是15用2进制表示是1111,刚好是4位二进制的最大值,不足4位的用0补位。

一个16进制是用4位2进制表示,所以转换前,可以先将2进制拆分为多个4位一组数据 比如010000,先进行补位,结果是 00010000,再拆分为0001和0000,换成16进制表示就是1和0 比如01111111,拆分为0111和1111,转成10进制是7和15,再转成16进制就是7F。

 

byte为什么要与上0xFF?

主要原因是byte输出转成int时,因为byte是8位,而int是32位,所以需要进行补位,如果是负数的情况下,前面会用1进行补位操作,这个时候生成的结果就不是我们想要的结果了。而和0xFF进行与操作是什么结果呢,0xFF用二进制表示是11111111,和这个进行与操作后,其实byte本身的结果不会变,但是前面的高位部分会被替换为0,这样就可以保持二进制数据的一致性。

详细的可以参数下面的链接文章,讲的比较详细了。 或者将下面这两个byte进行输出看下结果。

byte a = (byte) 0b01011010;
byte b = (byte) (0b10101010);
print(b & 0xFF);

输出结果:
01011010
11111111111111111111111110101010
10101010

显然第二个不是我们想要的结果,第三个和0xFF进行与操作后的结果才是我们真实想要的。

参考:https://blog.csdn.net/xiaozhouchou/article/details/79086604

posted @ 2020-08-01 14:35  胡大叔  阅读(285)  评论(0编辑  收藏  举报