前情回顾
在上一篇文章 重温Java基础(六):关系、布尔运算符中,介绍了Java中的关系运算符和布尔运算符,针对小于、大于、小于等于、大于等于、逻辑与、逻辑或、非、三元运算符等运算符进行了回顾。
本章重点
本章将介绍Java中的位运算符。
概述
Java中的位运算符包括 & ("and")、| ("or")、^ ("xor")、~ ("not")。这些运算符都按位模式处理。
与
两位均为1,结果才为1。
例如:(100)0110 0100 & (12)0000 1100 = (4)0000 0100
特别用法
清零
如果想将一个二进制单元清零,也就是全部二进制位为0,只要与一个各位都是零的值进行按位与,其结果必然为零。
例如:(12)0000 1100 & (0) 0000 0000 = (0)0000 0000
取指定位
取那些二进制位,只需将这些二进制位置为1,其余为0,然后在进行按位与,即可得到这些二进制位。
例如:(170)1010 1010 & (3) 0000 0011 = (2)0000 0010,得到了后2位二进制位。
例如:(170)1010 1010 & (7) 0000 0111 = (2)0000 0010,得到了后3位二进制位。
进阶方法(取单个二进制位)
用对应二进制位为1其它位为0的数,与其进行按位与,然后再进行除操作,返回1则代表其位置的二进制为1,否则为0,表达式为:int thridBitFormRight = (x & 0b100) / 0b100。
例如,x为14,二进制形式为0000 1110,从右往左数第3位为1,可与(36)0010 0100进行按位与,则结果必为1,((14)0000 1110 & (4)0b100 ) / (4)0b100 = 1。
这说明,利用&运算符,并结合适当的2的幂,可以把其它位掩掉,只保留其中的某一位。
或
只要有一个为1,结果就为1。
例如:(100)0110 0100 | (12)0000 1100 = (108)0110 1100。
特别用法
对应要置1的位,使这些位为1,其余为0,用此数与目标数按位或,即可使这些位为1。
例如:(100)0110 0100 | (155)1001 1011 = (255)1111 1111。
异或
对应值不同,结果为1,否则为0。
例如:(100)0110 0100 ^ (12)0000 1100 = (104)0110 1000。
取反
对一个二进制数按位取反,即0变1,1变0。
例如:~1 = -2;~0 = -1。
例如:~(100)0110 0100 = (-101)1001 1011
左移
将一个运算对象的各二进制位全部左移若干位,左边的二进制位丢弃,右边补0。
例如:1 << 3 = 8;10 << 1 = 20。
若左移时,舍弃的高位不包含1,则每左移一位,相当于该数乘以2。
例如:(11) 0000 1011 << 1 = (22) 0001 0110。
右移
将一个运算对象的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。若右移时舍高位不是1(即不是负数),操作数每右移一位,相当于该数除以2。
例如:8 >> 3 = 1,等同于8/2/2/2 = 1。
例如:-20 >> 2 = -5,等同于 -20/2/2 = -5。
例如:-19 >> 2 = -5,等同于( -19 >> 1 ) / 2 = -5,右移第二位时,舍弃高位为0,所以除以2,-10除以2等于-5。
无符号右移
各个位向右移指定的位数,右移后,左边空出的位由0来填充。右边移除的位丢弃。
例如:(-14) 11111111 11111111 11111111 11110010 >>> 2 = (1073741820)00111111 11111111 11111111 11111100。
源码
github
https://github.com/liuminglei/ReviewJavaFoundation/tree/master/07
gitee
https://gitee.com/xbd521/ReviewJavaFoundation/tree/master/07
笔者开通了个人微信公众号【银河架构师】,分享工作、生活过程中的心得体会,填坑指南,技术感悟等内容,会比博客提前更新,欢迎订阅。