今天在项目中看到一个两个变量互换值的写法,感觉很奇怪,代码是这样的:
int a = 3;
int b = 2;
a ^= b;
b ^= a;
a ^= b;
于是到网上查阅了相关资料,并写了自己的测试代码,同时对“&”,"|","^"运算符做了一些总结:
这几个运算符都涉及到二进制间的逻辑运算,为了便于理解,在二进制里,我们可以把1当做逻辑true,把0当做逻辑false。
测试代码如下:
package test;
public class Test {
public static void main(String[] args) {
int a = 3;
int b = 2;
test1(a, b);
test2(a, b);
test3(a, b);
test4(a);
}
public static void test1(int a, int b) {
System.out.println("a & b = " + (a & b));
}
public static void test2(int a, int b) {
System.out.println("a | b = " + (a | b));
}
public static void test3(int a, int b) {
System.out.println("a ^ b = " + (a ^ b));
}
public static void test4(int a){
System.out.println("~a = " + (~a));
}
}
1、“&”按位与运算符:
运算规则:参与运算的数字,低位对齐,高位不足的补零,对应的二进制位都为1,则运算结果为1,否则为0,因为任何数与0都得0。
例子中的计算过程:
3的二进制形式为0000 0000 0000 0000 0000 0000 0000 0011
2的二进制形式为0000 0000 0000 0000 0000 0000 0000 0010
按位进行与运算,结果为0000 0000 0000 0000 0000 0000 0000 0010
这个数字转换为十进制就是数字2.
2、“|”按位或运算符:
运算规则:参与运算的数字,低位对齐,高位不足的补零,对应的二进制位有一个为1则为1,否则为0,1和任何数或运算都是1。
例子中的计算过程:
3的二进制形式为0000 0000 0000 0000 0000 0000 0000 0011
2的二进制形式为0000 0000 0000 0000 0000 0000 0000 0010
按位进行或运算,结果为0000 0000 0000 0000 0000 0000 0000 0011
这个数字转换为十进制就是数字3.
3、“^”按位异或运算符:
运算规则:参与运算的数字,低位对齐,高位不足的补零,对应的二进制位相同为零,不相同为1。
例子中的计算过程: 3的二进制形式为0000 0000 0000 0000 0000 0000 0000 0011
2的二进制形式为0000 0000 0000 0000 0000 0000 0000 0010
按位进行或运算,结果为0000 0000 0000 0000 0000 0000 0000 0001
这个数字转换为十进制就是数字1.
4、“~”按位非运算:
按位非也叫做补,其实就是对二进制 先取反,再取反+1并添加上符号,就可以得到结果。
运算规则:只操作一个数字,将该数字中为1的位变成0,为0的位变成1。
适用场合:反转数字的内容
例子中的计算过程:
3的二进制形式为0000 0000 0000 0000 0000 0000 0000 0011 取反后:1111 1111 1111 1111 1111 1111 1111 1100
由于取反后得到的是一个负数的存贮形式,而负数时以补码的形式存贮,所以补码取反加1,转为十进制,再添加上符号就得到十进制形式的值。
即:
取反加1后的结果:0000 0000 0000 0000 0000 0000 0000 0011 + 1 = 0000 0000 0000 0000 0000 0000 0000 0100
转为成十进制并添加上符号,即最后的结果为:-4
所以,例子程序中最后的执行结果为:
a & b = 2
a | b = 3
a ^ b = 1
~a = -4