&, |, ^, ~ 这些符号什么意思?有什么妙用?一起来感受它们的神奇吧~
当我们看一些源码的时候,经常会看到诸如 &、|、^、~ 的符号,这些就是位运算符。
位运算是直接对一个整形的二进制位进行操作,效率上比起加减乘除高不少,因此常运用在对性能很敏感的场景。
在二进制格式下,将两个数的每一位(1或0)分别做与运算(1&1=1,其它=0),得到一个新的二进制数。
public class Bit { public static void main(String[] args) { /* * 十进制 二进制 * 5 0 1 0 1 从最低位(右)开始比较,不足的为0 * 与 与 * 14 1 1 1 0 * = = * 4 0 1 0 0 */ System.out.println(5 & 14); } } // 输出: 4
判断整数n是奇数还是偶数:
原理:二进制格式下,右边第一位是0则是偶数,反之为奇数,因此只需要和1进行与运算即可。
在二进制格式下,将两个数的每一位(1或0)分别做或运算(0|0=0,其它=1),得到一个新的二进制数。
public class Bit { public static void main(String[] args) { /* * 十进制 二进制 * 2 0 1 0 从最低位(右)开始比较,不足的为0 * 或 或 * 4 1 0 0 * = = * 6 1 1 0 */ System.out.println(2 | 4); } } // 输出: 6
在Linux系统中,文件权限管理用1、2、4分别表示执行x、写w、读r的权限。
可以看做一个三位的二进制数,每一位分别表示一种权限的开启与否(1开启,0关闭),通过或运算组合就得到了不同的权限组合。
所以最高权限就是7,即二进制的“111”,拥有读、写、执行全部权限。而777权限则是所属用户、组用户、其他用户都拥有最高权限。
基于这个思路,我们只需要一个int或者long型的数字就可以存储几十个布尔类型的属性值,在某些场景下很有用。
异或:相同为false,不同true
在二进制格式下,将两个数的每一位(1或0)分别做异或运算(0^0=0,1^1=0, 其它=1),得到一个新的二进制数。
public class Bit { public static void main(String[] args) { /* * 十进制 二进制 * 2 0 1 0 从最低位(右)开始比较,不足的为0 * 异或 异或 * 6 1 1 0 * = = * 4 1 0 0 */ System.out.println(2 ^ 6); } } // 输出: 4
异或有个有趣的特性,它的逆运算是它本身,即A^B=C,C^B=A。基于这个特点,可以做一个简单的加密,把B作为秘钥,原文A用秘钥B加密后进行传输或存储等,使用时再用秘钥B进行解密。
通过异或操作还能实现两个数的交换,不需要中间值。(简单测了下性能并没有很棒棒)
public class Bit { public static void main(String[] args) { int x = 2;// 010 int y = 4;// 100 x = x ^ y;// 110 y = y ^ x;// 010 x = x ^ y;// 100 System.out.println("x = " + x); System.out.println("y = " + y); } } /* 输出: x = 4 y = 2 */
在二进制格式下,将两个数的每一位(1或0)分别做非运算(~0=1,~1=0),得到一个新的二进制数。
public class Bit { public static void main(String[] args) { System.out.println(~1); } } // 输出: -2
1进行非运算后值成了负数,不只是1,只要是正数,取非后都是负数,因为对于有符号的整数,最高位(最左边)是用来表示正负的,最高位为0是正数,1是负数。
正数1非运算后从“00000000000000000000000000000001”变成了“11111111111111111111111111111110”。
二进制表示负数的情况,要转成十进制需要两个步骤:
通过位运算可以巧妙且高效地达到某些目的,但如果不是很有必要,并不建议使用,毕竟可读性不高,别人看起来太痛苦(想想在阅读源码时看到一堆位运算的心情)。
这次简单介绍了与、或、非、异或,下次再讲讲移位操作的实践。
本文分享自微信公众号 - 一杯82年的JAVA(acupjava),作者:acupt
原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。
原始发表时间:2019-08-30
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句