前言
最近在看HashMap源码时发现,源码中含有大量的此类运算符号,所以就总结一下
按位与
按位与运算符(&)
按位或
按位或运算符(|)
异或
异或运算符(^)
Java中的移位运算有三种,分别是
<<
左移运算符
>>
右移运算符
>>>
无符号右移运算符
接下来我们测试,每个运算符的运算特性
按位与运算符(&)
按位与(&)
参加运算的两个数据,按二进制位进行“与”运算。
运算规则:0&0=0; 0&1=0; 1&0=0; 1&1=1;
即:两位同时为“1”,结果才为“1”,否则为0。一假即为假,
public class Yu {
public static void main(String[] args) {
System.out.println(3 & 4);
System.out.println(3 & 5);
}
}
/*
3 011
5 101
-------
001
所以3&5 == 1
3 011
4 100
-------
000
所以3&4==0
*/
public class Yu {
public static void main(String[] args) {
System.out.println(3>0 & 0>2 );
System.out.println(3>0 & 0<2 );
}
}
注意,清零操作
如果想将一个单元清零,即使其全部二进制位为0,只要与一个各位都为零的数值相与,结果为零。
异或(^)
参加运算的两个数据,按二进制位进行“异或”运算。
运算规则:0 ^ 0=0; 0 ^ 1=1; 1 ^ 0=1; 1 ^ 1=0;
即:参加运算的两个对象,如果两个相应位为“异”(值不同),则该位结果为1,否则为0。
public class YiHuo {
public static void main(String[] args) {
System.out.println(1^2);
System.out.println(3^4);
System.out.println(3^5);
System.out.println(1^0);
System.out.println(0^1);
System.out.println(0^0);
System.out.println(1^1);
System.out.println(1<0 ^ 2<0);
System.out.println(1<0 ^ 2>0);
System.out.println(1>0 ^ 2>0);
}
}
/*
1 001
2 010
-----
011
所以为3
3 011
4 100
-----
111
所以为7
3 011
5 101
------
110
所以为6
*/
按位或运算符(|)
参加运算的两个对象,按二进制位进行“或”运算。
运算规则:0|0=0; 0|1=1; 1|0=1; 1|1=1;
即 :参加运算的两个对象只要有一个为1,其值为1。一真即为真
public class Huo {
public static void main(String[] args) {
System.out.println(1 | 0);
System.out.println(1 | 1);
System.out.println(0 | 0);
System.out.println(3>2 | 2<0);
System.out.println(3 | 4);
System.out.println(3 | 5);
}
}
/*
3 011
4 100
-------
111
所以结果为7
3 011
5 101
-------
111
*/
左移运算符(<<)
public class TestFuhao{
public static void main(String[] args) {
int num = 3;
printByte(num);
num = num << 1;
printByte(num);
System.out.println(num);
}
/**
* 输出一个数的二进制
* @param i 传的参数
*/
private static void printByte(int i) {
System.out.println(Integer.toBinaryString(i));
}
}
public class TestFuhao{
public static void main(String[] args) {
int num = 3;
printByte(num);
num = num << 2;
printByte(num);
System.out.println(num);
}
/**
* 输出一个数的二进制
* @param i 传的参数
*/
private static void printByte(int i) {
System.out.println(Integer.toBinaryString(i));
}
}
我们发现3<<1
结果为6
我们发现3<<2
结果为12
所以我们发现左移一位末尾添一个0
二进制转换为十进制的算法为:
数字3的二进制转十进制 11 =121+ 120;
数字12的二进制转十进制 1100 = 123 + 122 + 021 + 020
右移运算符(>>)
public class AnweiYu2 {
public static void main(String[] args) {
int num = 3;
printByte(num);
num = num >> 1;
printByte(num);
System.out.println(num);
}
/**
* 输出一个数的二进制
* @param i 传的参数
*/
private static void printByte(int i) {
System.out.println(Integer.toBinaryString(i));
}
}
public class AnweiYu2 {
public static void main(String[] args) {
int num = 9;
printByte(num);
num = num >> 2;
printByte(num);
System.out.println(num);
}
/**
* 输出一个数的二进制
* @param i 传的参数
*/
private static void printByte(int i) {
System.out.println(Integer.toBinaryString(i));
}
}
总结
根据上面的运算规则,我们发现一个规律,简单的来记,就是左移移运算符是原来的数乘以2,右移运算符是原来的数除以2
原因:
通过例子来解释
假设现在有一个二进制数据:10000
该数据的十进制数据为:16
现在我们将二进制数据左移一位,二进制数据变为:100000
该数据的十进制数据为:32
将二进制数据10000右移一位,二进制数据变为:1000
该数据的十进制数据为:8
所以我们可以简单的记为:左移移运算符是原来的数乘以2,右移运算符是原来的数除以2